Compare commits

...

52 Commits
1.9.2 ... 1.9.7

Author SHA1 Message Date
Felix Fontein
928cb3aa9b Release 1.9.7. 2021-11-22 11:41:02 +01:00
patchback[bot]
3e6815d73f [PR #331/3f40795a backport][stable-1] Extension parsing: add new fallback code which uses the new cryptography API (#345)
* Extension parsing: add new fallback code which uses the new cryptography API (#331)

* Add new code as fallback which re-serializes de-serialized extensions using the new cryptography API.

* Forgot Base64 encoding.

* Add extension by OID tests.

* There's one value which is different with the new code.

* Differences in CI.

* Working around older Jinjas.

* Value depends on which SAN was included.

* Force complete CI run now since cryptography 36.0.0 is out.

ci_complete

(cherry picked from commit 3f40795a98)

* Adjust tests.

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-22 08:54:08 +01:00
patchback[bot]
cb08f56066 Use new PKCS#12 deserialization code from cryptography 36.0.0 if available (#302) (#344)
* Use new PKCS#12 deserialization code from cryptography 36.0.0 if available.

* Refactor into smaller functions.

* Force complete CI run now since cryptography 36.0.0 is out.

ci_complete

(cherry picked from commit 73bc0f5de7)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-22 08:27:33 +01:00
Felix Fontein
e3f486a063 Prepare 1.9.7 releaese. 2021-11-22 07:41:21 +01:00
patchback[bot]
0a1e25e16a Fix collection dependency installation in CI. (#341) (#342)
(cherry picked from commit f1a6baadc7)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-18 21:21:57 +01:00
patchback[bot]
ff4966ad3f Fix compatibility to fetch_url change in ansible-core devel (#339) (#340)
* Fix compatibility to fetch_url change in ansible-core devel.

* Adjust tests.

(cherry picked from commit 5de50b9f91)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-17 21:46:13 +01:00
patchback[bot]
0cb10be2d5 Replace RHEL 8.4 by RHEL 8.5 for devel. (#337) (#338)
(cherry picked from commit cf0d2679aa)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-17 07:07:31 +00:00
patchback[bot]
901863989b This is no longer a problem with the dev version of cryptography. (#335) (#336)
(cherry picked from commit 2d388bf8d0)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-13 23:31:52 +01:00
Felix Fontein
99377764c1 Replace Bash codecov uploader by new Python codecov uploader. (#333) (#334)
ci_coverage

(cherry picked from commit 056a86fcae)
2021-11-13 13:22:01 +01:00
patchback[bot]
426d70fbcf luks_device: add built-in signature wiper to work around older wipefs versions with LUKS2 containers (#327) (#330)
* Use 'cryptsetup erase' to kill LUKS signature.

* Adjust unit test.

* Use own wiper for LUKS headers.

* Add comments.

* Fix tests.

* Update changelog.

* Remove 'cryptsetup erase'.

* Improve error messages.

(cherry picked from commit ebbfd7c56f)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-11 07:17:45 +01:00
patchback[bot]
f315722b31 Replace Fedora 33 with Fedora 35 for devel tests. (#328) (#329)
(cherry picked from commit 91d98c4413)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-09 05:52:42 +01:00
patchback[bot]
73afe8e742 acme_certificate: fix crash when using fullchain_dest (#324) (#325)
* Fix crash when using fullchain_dest.

* Adjust changelog.

* Update plugins/module_utils/acme/backend_cryptography.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 51b6bb210d)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-05 09:35:10 +01:00
Felix Fontein
db67b8a857 Next expected release is 1.9.7. 2021-10-30 18:21:40 +02:00
Felix Fontein
e05475d58a Release 1.9.6. 2021-10-30 17:48:48 +02:00
Felix Fontein
dceee8f50e Prepare 1.9.6 release. 2021-10-30 17:07:49 +02:00
Felix Fontein
b893252ad1 [stable-1] cryptography support: improve Python 2 Unicode handling (#314)
* Improve Python 2 Unicode handling. (#313)

(cherry picked from commit eb8dabce84)

* Remove test since it doesn't work with pyOpenSSL.

* Completely remove test.

* Update plugins/module_utils/crypto/cryptography_support.py
2021-10-29 21:10:57 +02:00
patchback[bot]
0755a2b657 Remove centos8 for devel from CI. (#307) (#308)
(cherry picked from commit 78b27ffedb)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-16 09:27:45 +02:00
Felix Fontein
90bf8b0b2e Adjust to latest devel changes.
(cherry picked from commit e735bdab60)
2021-10-12 19:32:56 +02:00
patchback[bot]
5ff28c751d Fix shellcheck error. (#303) (#304)
(cherry picked from commit c68bfedbaa)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-08 15:10:41 +02:00
Felix Fontein
7b08edb5a4 Next expected release is 1.9.6. 2021-10-06 13:35:44 +02:00
Felix Fontein
fbadcbeb29 Release 1.9.5. 2021-10-06 13:08:43 +02:00
Felix Fontein
e991375f55 Prepare 1.9.5 release. 2021-10-05 22:28:03 +02:00
Felix Fontein
33c99014ae [stable-1] Fix PyOpenSSL backends with cryptography 35.0.0 (#300)
* Try to make compatible with cryptography 35.0.0.

* Forgot import.

ci_complete

* Add changelog fragment.
2021-10-05 22:19:11 +02:00
patchback[bot]
fbd6ff6ead x509_certificate: document that *notBefore/*notAfter are not used for idempotency (#298) (#301)
* Document that *notBefore/*notAfter are not used for idempotency.

* Change formulation.

(cherry picked from commit ed03841fd1)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-03 22:20:34 +02:00
patchback[bot]
c4ab2eb3b5 Fix PKCS#12 friendly name extraction for cryptography 35.0.0. (#296) (#299)
(cherry picked from commit d6c0d53442)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-03 21:37:37 +02:00
patchback[bot]
44b6df0ce5 Support cryptography 35.0.0 for all modules except openssl_pkcs12 (#294) (#297)
* Add some workarounds for cryptography 35.0.0.

* Make fix work with very old cryptography versions as well (which supported multiple backends).

* [TEMP] Disable openssl_pkcs12 tests to see whether everything else works.

* Revert "[TEMP] Disable openssl_pkcs12 tests to see whether everything else works."

This reverts commit 3f905bc795.

* Add changelog fragment.

* Remove unnecessary assignment.

* Simplify code change.

* [TEMP] Disable openssl_pkcs12 tests to see whether everything else works.

* Revert "[TEMP] Disable openssl_pkcs12 tests to see whether everything else works."

This reverts commit fdb210528e.

(cherry picked from commit a2a7d94055)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-03 17:23:35 +02:00
Felix Fontein
14a42505a9 Ansible-core devel dropped support for Python 2.6.
(cherry picked from commit 2a7e452cf8)
2021-10-01 13:46:08 +02:00
Felix Fontein
44cbd33cb7 Run CI on stable branches only once per week.
(cherry picked from commit 24e7d07973)
2021-10-01 13:44:44 +02:00
Felix Fontein
4411a71d06 Temporarily fix CI for cryptography 35.0.0 release. (#292)
(cherry picked from commit 57c364fe87)
2021-09-30 13:45:38 +02:00
Felix Fontein
bfe37bc668 Next expected 1.x.y release is 1.9.5. 2021-09-28 17:31:41 +02:00
Felix Fontein
d784e0a52b Release 1.9.4. 2021-09-28 17:17:41 +02:00
Felix Fontein
d73a2942a2 Prepare 1.9.4 release. 2021-09-28 16:53:56 +02:00
Felix Fontein
8af4847373 Update CI matrix to include ansible-core's stable-2.12 branch (#286)
* Update CI matrix to include ansible-core's stable-2.12 branch.

* Adjust README.

* Fix stage names.
2021-09-28 15:35:26 +02:00
Felix Fontein
44f7367e21 Extend CI (#283)
* Run all tests on all targets. Remove hack in setup_acme.

* Fix some failing tests.

* OpenSSH tests do not work yet with default image on Ansible 2.9. Let's skip them on the cloud target.

* Make tests pass again.

* Make sure to install *latest* versions of cryptography and pyOpenSSL when not installing system packages, whenever possible.

ci_complete

* Update/fix aliases files.
2021-09-25 17:21:06 +02:00
Felix Fontein
0733b0d521 Prepare ansible-core devel branch version bump that is planned for later today. 2021-09-24 18:45:50 +02:00
Ajpantuso
771a9eebcf Initial commit (#285) 2021-09-24 06:59:52 +02:00
Felix Fontein
0fdede5d7a Fix CI (1/2) (#284)
* New default docker image no longer contains bcrypt.

* Install cryptography for ACME tests.

* Add constraints.
2021-09-23 21:56:03 +02:00
Felix Fontein
56b2130c6e openssl_privatekey_pipe is an action plugin. (#267) 2021-09-21 07:29:26 +02:00
Felix Fontein
6c018b94da Improve CI (#281)
* Install PyOpenSSL and cryptography from PyPi if target Python != system Python.

* Work around some CentOS6, 7, Ubuntu 16.04 problems. Improve jinja2 compatibility handling.

* Skip tasks that require properties that aren't always there.

* Only install OpenSSL when not present.

* Improve output.

* Improve get_certificate integration test graceful failing.

* Fix tests.

* Fix assert.

* OpenSSL peculiarities.

* Fix condition.
2021-09-18 15:21:40 +02:00
Felix Fontein
63f4598737 acme_challenge_cert_helper: fail better to avoid crashes in Ansible (#282)
* Prevent acme_challenge_cert_helper triggering a bug in Ansible.

* Add changelog fragment.
2021-09-17 19:35:43 +02:00
Felix Fontein
598cdf0a21 Older openssl versions (1.0.1/1.0.2) do not seem to support '-' for /dev/stdin. (#279) 2021-09-15 20:42:52 +02:00
Ajpantuso
eea7bfc6bf openssh_cert - adding signature_algorithm option (#277)
* Initial Commit

* Update supported OpenSSH versions for RSA SHA-2 signed certs

* Updating 'regenerate' documentation
2021-09-15 08:53:53 +02:00
Felix Fontein
8521c96e8a Next expected release is 1.10.0. 2021-09-14 12:33:06 +02:00
Felix Fontein
d90cc5142b Release 1.9.3. 2021-09-14 08:15:32 +02:00
Felix Fontein
37aab65396 Prepare 1.9.3 release. 2021-09-14 07:14:03 +02:00
Felix Fontein
baff003ea8 Fix changelog from last time. 2021-09-14 07:13:25 +02:00
Felix Fontein
03427e35a7 Fix idempotency for non-ASCII string comparisons. (#271) 2021-09-14 07:06:35 +02:00
Felix Fontein
170fa40014 ipaddress is part of stdlib for Python 3. (#275) 2021-09-12 17:21:10 +02:00
Felix Fontein
330b30d5d2 certificate_complete_chain tests need cryptography installed on the target, so use setup_openssl. (#272) 2021-09-11 11:29:03 +02:00
Felix Fontein
67b8274faf openssl_csr: fix error in docs (#269)
* Fix error in docs.

* Add missing word.
2021-09-10 20:53:50 +02:00
Felix Fontein
02ee3fb974 Improve CI (#268)
* Remove superfluous remote_src.

* Use temp dir twice instead of output_dir.

* Use remote temp directory instead of output_dir.

* Fix syntax error.

* Add some fixes.

* Copy more files to remote.

* More fixes.

* Fixing ACME/'cloud' tests.

* Forgot when.

* Try to fix filters.

* Skip unnecessary steps.

* Avoid collision.
2021-09-07 22:37:40 +02:00
Felix Fontein
93ced1956c The next expected release is again 1.10.0. 2021-08-30 22:01:49 +02:00
179 changed files with 3150 additions and 1711 deletions

View File

@@ -19,6 +19,11 @@ schedules:
branches: branches:
include: include:
- main - main
- cron: 0 12 * * 0
displayName: Weekly (old stable branches)
always: true
branches:
include:
- stable-* - stable-*
variables: variables:
@@ -55,6 +60,17 @@ stages:
test: 'devel/sanity/extra' test: 'devel/sanity/extra'
- name: Units - name: Units
test: 'devel/units/1' test: 'devel/units/1'
- stage: Ansible_2_12
displayName: Sanity & Units 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Sanity
test: '2.12/sanity/1'
- name: Units
test: '2.12/units/1'
- stage: Ansible_2_11 - stage: Ansible_2_11
displayName: Sanity & Units 2.11 displayName: Sanity & Units 2.11
dependsOn: [] dependsOn: []
@@ -97,16 +113,12 @@ stages:
parameters: parameters:
testFormat: devel/linux/{0}/1 testFormat: devel/linux/{0}/1
targets: targets:
- name: CentOS 6
test: centos6
- name: CentOS 7 - name: CentOS 7
test: centos7 test: centos7
- name: CentOS 8
test: centos8
- name: Fedora 33
test: fedora33
- name: Fedora 34 - name: Fedora 34
test: fedora34 test: fedora34
- name: Fedora 35
test: fedora35
- name: openSUSE 15 py2 - name: openSUSE 15 py2
test: opensuse15py2 test: opensuse15py2
- name: openSUSE 15 py3 - name: openSUSE 15 py3
@@ -115,6 +127,24 @@ stages:
test: ubuntu1804 test: ubuntu1804
- name: Ubuntu 20.04 - name: Ubuntu 20.04
test: ubuntu2004 test: ubuntu2004
- stage: Docker_2_12
displayName: Docker 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.12/linux/{0}/1
targets:
- name: CentOS 6
test: centos6
- name: CentOS 8
test: centos8
- name: Fedora 33
test: fedora33
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 20.04
test: ubuntu2004
- stage: Docker_2_11 - stage: Docker_2_11
displayName: Docker 2.11 displayName: Docker 2.11
dependsOn: [] dependsOn: []
@@ -131,12 +161,8 @@ stages:
test: fedora32 test: fedora32
- name: openSUSE 15 py2 - name: openSUSE 15 py2
test: opensuse15py2 test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 18.04 - name: Ubuntu 18.04
test: ubuntu1804 test: ubuntu1804
- name: Ubuntu 20.04
test: ubuntu2004
- stage: Docker_2_10 - stage: Docker_2_10
displayName: Docker 2.10 displayName: Docker 2.10
dependsOn: [] dependsOn: []
@@ -147,22 +173,10 @@ stages:
targets: targets:
- name: CentOS 6 - name: CentOS 6
test: centos6 test: centos6
- name: CentOS 7
test: centos7
- name: CentOS 8
test: centos8
- name: Fedora 31 - name: Fedora 31
test: fedora31 test: fedora31
- name: Fedora 32
test: fedora32
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 16.04 - name: Ubuntu 16.04
test: ubuntu1604 test: ubuntu1604
- name: Ubuntu 18.04
test: ubuntu1804
- stage: Docker_2_9 - stage: Docker_2_9
displayName: Docker 2.9 displayName: Docker 2.9
dependsOn: [] dependsOn: []
@@ -175,16 +189,8 @@ stages:
test: centos6 test: centos6
- name: CentOS 7 - name: CentOS 7
test: centos7 test: centos7
- name: CentOS 8
test: centos8
- name: Fedora 30
test: fedora30
- name: Fedora 31 - name: Fedora 31
test: fedora31 test: fedora31
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 16.04 - name: Ubuntu 16.04
test: ubuntu1604 test: ubuntu1604
- name: Ubuntu 18.04 - name: Ubuntu 18.04
@@ -203,12 +209,26 @@ stages:
test: macos/11.1 test: macos/11.1
- name: RHEL 7.9 - name: RHEL 7.9
test: rhel/7.9 test: rhel/7.9
- name: RHEL 8.4 - name: RHEL 8.5
test: rhel/8.4 test: rhel/8.5
- name: FreeBSD 12.2 - name: FreeBSD 12.2
test: freebsd/12.2 test: freebsd/12.2
- name: FreeBSD 13.0 - name: FreeBSD 13.0
test: freebsd/13.0 test: freebsd/13.0
- stage: Remote_2_12
displayName: Remote 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.12/{0}/1
targets:
- name: macOS 11.1
test: macos/11.1
- name: RHEL 8.4
test: rhel/8.4
- name: FreeBSD 13.0
test: freebsd/13.0
- stage: Remote_2_11 - stage: Remote_2_11
displayName: Remote 2.11 displayName: Remote 2.11
dependsOn: [] dependsOn: []
@@ -221,8 +241,6 @@ stages:
test: rhel/7.9 test: rhel/7.9
- name: RHEL 8.3 - name: RHEL 8.3
test: rhel/8.3 test: rhel/8.3
- name: macOS 11.1
test: macos/11.1
- name: FreeBSD 12.2 - name: FreeBSD 12.2
test: freebsd/12.2 test: freebsd/12.2
- stage: Remote_2_10 - stage: Remote_2_10
@@ -233,8 +251,6 @@ stages:
parameters: parameters:
testFormat: 2.10/{0}/1 testFormat: 2.10/{0}/1
targets: targets:
- name: RHEL 7.8
test: rhel/7.8
- name: OS X 10.11 - name: OS X 10.11
test: osx/10.11 test: osx/10.11
- name: macOS 10.15 - name: macOS 10.15
@@ -261,7 +277,6 @@ stages:
nameFormat: Python {0} nameFormat: Python {0}
testFormat: devel/cloud/{0}/1 testFormat: devel/cloud/{0}/1
targets: targets:
- test: 2.6
- test: 2.7 - test: 2.7
- test: 3.5 - test: 3.5
- test: 3.6 - test: 3.6
@@ -269,6 +284,17 @@ stages:
- test: 3.8 - test: 3.8
- test: 3.9 - test: 3.9
- test: "3.10" - test: "3.10"
- stage: Cloud_2_12
displayName: Cloud 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.12/cloud/{0}/1
targets:
- test: 2.6
- test: 3.9
- stage: Cloud_2_11 - stage: Cloud_2_11
displayName: Cloud 2.11 displayName: Cloud 2.11
dependsOn: [] dependsOn: []
@@ -306,20 +332,24 @@ stages:
condition: succeededOrFailed() condition: succeededOrFailed()
dependsOn: dependsOn:
- Ansible_devel - Ansible_devel
- Ansible_2_12
- Ansible_2_11 - Ansible_2_11
- Ansible_2_10 - Ansible_2_10
- Ansible_2_9 - Ansible_2_9
- Remote_devel - Remote_devel
- Docker_devel - Remote_2_12
- Cloud_devel
- Remote_2_11 - Remote_2_11
- Docker_2_11
- Cloud_2_11
- Remote_2_10 - Remote_2_10
- Docker_2_10
- Cloud_2_10
- Remote_2_9 - Remote_2_9
- Docker_devel
- Docker_2_12
- Docker_2_11
- Docker_2_10
- Docker_2_9 - Docker_2_9
- Cloud_devel
- Cloud_2_12
- Cloud_2_11
- Cloud_2_10
- Cloud_2_9 - Cloud_2_9
jobs: jobs:
- template: templates/coverage.yml - template: templates/coverage.yml

View File

@@ -11,7 +11,7 @@ mkdir "${agent_temp_directory}/coverage/"
options=(--venv --venv-system-site-packages --color -v) options=(--venv --venv-system-site-packages --color -v)
ansible-test coverage combine --export "${agent_temp_directory}/coverage/" "${options[@]}" ansible-test coverage combine --group-by command --export "${agent_temp_directory}/coverage/" "${options[@]}"
if ansible-test coverage analyze targets generate --help >/dev/null 2>&1; then if ansible-test coverage analyze targets generate --help >/dev/null 2>&1; then
# Only analyze coverage if the installed version of ansible-test supports it. # Only analyze coverage if the installed version of ansible-test supports it.

View File

@@ -0,0 +1,101 @@
#!/usr/bin/env python
"""
Upload code coverage reports to codecov.io.
Multiple coverage files from multiple languages are accepted and aggregated after upload.
Python coverage, as well as PowerShell and Python stubs can all be uploaded.
"""
import argparse
import dataclasses
import pathlib
import shutil
import subprocess
import tempfile
import typing as t
import urllib.request
@dataclasses.dataclass(frozen=True)
class CoverageFile:
name: str
path: pathlib.Path
flags: t.List[str]
@dataclasses.dataclass(frozen=True)
class Args:
dry_run: bool
path: pathlib.Path
def parse_args() -> Args:
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--dry-run', action='store_true')
parser.add_argument('path', type=pathlib.Path)
args = parser.parse_args()
# Store arguments in a typed dataclass
fields = dataclasses.fields(Args)
kwargs = {field.name: getattr(args, field.name) for field in fields}
return Args(**kwargs)
def process_files(directory: pathlib.Path) -> t.Tuple[CoverageFile, ...]:
processed = []
for file in directory.joinpath('reports').glob('coverage*.xml'):
name = file.stem.replace('coverage=', '')
# Get flags from name
flags = name.replace('-powershell', '').split('=') # Drop '-powershell' suffix
flags = [flag if not flag.startswith('stub') else flag.split('-')[0] for flag in flags] # Remove "-01" from stub files
processed.append(CoverageFile(name, file, flags))
return tuple(processed)
def upload_files(codecov_bin: pathlib.Path, files: t.Tuple[CoverageFile, ...], dry_run: bool = False) -> None:
for file in files:
cmd = [
str(codecov_bin),
'--name', file.name,
'--file', str(file.path),
]
for flag in file.flags:
cmd.extend(['--flags', flag])
if dry_run:
print(f'DRY-RUN: Would run command: {cmd}')
continue
subprocess.run(cmd, check=True)
def download_file(url: str, dest: pathlib.Path, flags: int, dry_run: bool = False) -> None:
if dry_run:
print(f'DRY-RUN: Would download {url} to {dest} and set mode to {flags:o}')
return
with urllib.request.urlopen(url) as resp:
with dest.open('w+b') as f:
# Read data in chunks rather than all at once
shutil.copyfileobj(resp, f, 64 * 1024)
dest.chmod(flags)
def main():
args = parse_args()
url = 'https://ansible-ci-files.s3.amazonaws.com/codecov/linux/codecov'
with tempfile.TemporaryDirectory(prefix='codecov-') as tmpdir:
codecov_bin = pathlib.Path(tmpdir) / 'codecov'
download_file(url, codecov_bin, 0o755, args.dry_run)
files = process_files(args.path)
upload_files(codecov_bin, files, args.dry_run)
if __name__ == '__main__':
main()

View File

@@ -1,27 +0,0 @@
#!/usr/bin/env bash
# Upload code coverage reports to codecov.io.
# Multiple coverage files from multiple languages are accepted and aggregated after upload.
# Python coverage, as well as PowerShell and Python stubs can all be uploaded.
set -o pipefail -eu
output_path="$1"
curl --silent --show-error https://ansible-ci-files.s3.us-east-1.amazonaws.com/codecov/codecov.sh > codecov.sh
for file in "${output_path}"/reports/coverage*.xml; do
name="${file}"
name="${name##*/}" # remove path
name="${name##coverage=}" # remove 'coverage=' prefix if present
name="${name%.xml}" # remove '.xml' suffix
bash codecov.sh \
-f "${file}" \
-n "${name}" \
-X coveragepy \
-X gcov \
-X fix \
-X search \
-X xcode \
|| echo "Failed to upload code coverage report to codecov.io: ${file}"
done

View File

@@ -12,4 +12,4 @@ if ! ansible-test --help >/dev/null 2>&1; then
pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
fi fi
ansible-test coverage xml --stub --venv --venv-system-site-packages --color -v ansible-test coverage xml --group-by command --stub --venv --venv-system-site-packages --color -v

View File

@@ -33,7 +33,7 @@ jobs:
summaryFileLocation: "$(outputPath)/reports/$(pipelinesCoverage).xml" summaryFileLocation: "$(outputPath)/reports/$(pipelinesCoverage).xml"
displayName: Publish to Azure Pipelines displayName: Publish to Azure Pipelines
condition: gt(variables.coverageFileCount, 0) condition: gt(variables.coverageFileCount, 0)
- bash: .azure-pipelines/scripts/publish-codecov.sh "$(outputPath)" - bash: .azure-pipelines/scripts/publish-codecov.py "$(outputPath)"
displayName: Publish to codecov.io displayName: Publish to codecov.io
condition: gt(variables.coverageFileCount, 0) condition: gt(variables.coverageFileCount, 0)
continueOnError: true continueOnError: true

View File

@@ -5,6 +5,101 @@ Community Crypto Release Notes
.. contents:: Topics .. contents:: Topics
v1.9.7
======
Release Summary
---------------
Bugfix release with extra forward compatibility for newer versions of cryptography.
Minor Changes
-------------
- acme_* modules - fix usage of ``fetch_url`` with changes in latest ansible-core ``devel`` branch (https://github.com/ansible-collections/community.crypto/pull/339).
Bugfixes
--------
- acme_certificate - avoid passing multiple certificates to ``cryptography``'s X.509 certificate loader when ``fullchain_dest`` is used (https://github.com/ansible-collections/community.crypto/pull/324).
- get_certificate, openssl_csr_info, x509_certificate_info - add fallback code for extension parsing that works with cryptography 36.0.0 and newer. This code re-serializes de-serialized extensions and thus can return slightly different values if the extension in the original CSR resp. certificate was not canonicalized correctly. This code is currently used as a fallback if the existing code stops working, but we will switch it to be the main code in a future release (https://github.com/ansible-collections/community.crypto/pull/331).
- luks_device - now also runs a built-in LUKS signature cleaner on ``state=absent`` to make sure that also the secondary LUKS2 header is wiped when older versions of wipefs are used (https://github.com/ansible-collections/community.crypto/issues/326, https://github.com/ansible-collections/community.crypto/pull/327).
- openssl_pkcs12 - use new PKCS#12 deserialization infrastructure from cryptography 36.0.0 if available (https://github.com/ansible-collections/community.crypto/pull/302).
v1.9.6
======
Release Summary
---------------
Regular bugfix release.
Bugfixes
--------
- cryptography backend - improve Unicode handling for Python 2 (https://github.com/ansible-collections/community.crypto/pull/313).
v1.9.5
======
Release Summary
---------------
Bugfix release to fully support cryptography 35.0.0.
Bugfixes
--------
- get_certificate - fix compatibility with the cryptography 35.0.0 release (https://github.com/ansible-collections/community.crypto/pull/294).
- openssl_csr_info - fix compatibility with the cryptography 35.0.0 release (https://github.com/ansible-collections/community.crypto/pull/294).
- openssl_csr_info - fix compatibility with the cryptography 35.0.0 release in PyOpenSSL backend (https://github.com/ansible-collections/community.crypto/pull/300).
- openssl_pkcs12 - fix compatibility with the cryptography 35.0.0 release (https://github.com/ansible-collections/community.crypto/pull/296).
- x509_certificate_info - fix compatibility with the cryptography 35.0.0 release (https://github.com/ansible-collections/community.crypto/pull/294).
- x509_certificate_info - fix compatibility with the cryptography 35.0.0 release in PyOpenSSL backend (https://github.com/ansible-collections/community.crypto/pull/300).
v1.9.4
======
Release Summary
---------------
Regular bugfix release.
Bugfixes
--------
- acme_* modules - fix commands composed for OpenSSL backend to retrieve information on CSRs and certificates from stdin to use ``/dev/stdin`` instead of ``-``. This is needed for OpenSSL 1.0.1 and 1.0.2, apparently (https://github.com/ansible-collections/community.crypto/pull/279).
- acme_challenge_cert_helper - only return exception when cryptography is not installed, not when a too old version of it is installed. This prevents Ansible's callback to crash (https://github.com/ansible-collections/community.crypto/pull/281).
v1.9.3
======
Release Summary
---------------
Regular bugfix release.
Bugfixes
--------
- openssl_csr and openssl_csr_pipe - make sure that Unicode strings are used to compare strings with the cryptography backend. This fixes idempotency problems with non-ASCII letters on Python 2 (https://github.com/ansible-collections/community.crypto/issues/270, https://github.com/ansible-collections/community.crypto/pull/271).
v1.9.2
======
Release Summary
---------------
Bugfix release to fix the changelog. No other change compared to 1.9.0.
v1.9.1
======
Release Summary
---------------
Accidental 1.9.1 release. Identical to 1.9.0.
v1.9.0 v1.9.0
====== ======

View File

@@ -11,7 +11,7 @@ Please note that this collection does **not** support Windows targets.
## Tested with Ansible ## Tested with Ansible
Tested with the current Ansible 2.9, ansible-base 2.10 and ansible-core 2.11 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported. Tested with the current Ansible 2.9, ansible-base 2.10, ansible-core 2.11 and ansible-core 2.12 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported.
## External requirements ## External requirements

View File

@@ -528,3 +528,97 @@ releases:
changes: changes:
release_summary: Accidental 1.9.1 release. Identical to 1.9.0. release_summary: Accidental 1.9.1 release. Identical to 1.9.0.
release_date: '2021-08-30' release_date: '2021-08-30'
1.9.2:
changes:
release_summary: Bugfix release to fix the changelog. No other change compared
to 1.9.0.
fragments:
- 1.9.2.yml
release_date: '2021-08-30'
1.9.3:
changes:
bugfixes:
- openssl_csr and openssl_csr_pipe - make sure that Unicode strings are used
to compare strings with the cryptography backend. This fixes idempotency problems
with non-ASCII letters on Python 2 (https://github.com/ansible-collections/community.crypto/issues/270,
https://github.com/ansible-collections/community.crypto/pull/271).
release_summary: Regular bugfix release.
fragments:
- 1.9.3.yml
- 271-openssl_csr-utf8.yml
release_date: '2021-09-14'
1.9.4:
changes:
bugfixes:
- acme_* modules - fix commands composed for OpenSSL backend to retrieve information
on CSRs and certificates from stdin to use ``/dev/stdin`` instead of ``-``.
This is needed for OpenSSL 1.0.1 and 1.0.2, apparently (https://github.com/ansible-collections/community.crypto/pull/279).
- acme_challenge_cert_helper - only return exception when cryptography is not
installed, not when a too old version of it is installed. This prevents Ansible's
callback to crash (https://github.com/ansible-collections/community.crypto/pull/281).
release_summary: Regular bugfix release.
fragments:
- 1.9.4.yml
- 279-acme-openssl.yml
- 282-acme_challenge_cert_helper-error.yml
release_date: '2021-09-28'
1.9.5:
changes:
bugfixes:
- get_certificate - fix compatibility with the cryptography 35.0.0 release (https://github.com/ansible-collections/community.crypto/pull/294).
- openssl_csr_info - fix compatibility with the cryptography 35.0.0 release
(https://github.com/ansible-collections/community.crypto/pull/294).
- openssl_csr_info - fix compatibility with the cryptography 35.0.0 release
in PyOpenSSL backend (https://github.com/ansible-collections/community.crypto/pull/300).
- openssl_pkcs12 - fix compatibility with the cryptography 35.0.0 release (https://github.com/ansible-collections/community.crypto/pull/296).
- x509_certificate_info - fix compatibility with the cryptography 35.0.0 release
(https://github.com/ansible-collections/community.crypto/pull/294).
- x509_certificate_info - fix compatibility with the cryptography 35.0.0 release
in PyOpenSSL backend (https://github.com/ansible-collections/community.crypto/pull/300).
release_summary: Bugfix release to fully support cryptography 35.0.0.
fragments:
- 1.9.5.yml
- 294-cryptography-35.0.0.yml
- 296-openssl_pkcs12-cryptography-35.yml
- 300-pyopenssl-cryptography-35.yml
release_date: '2021-10-06'
1.9.6:
changes:
bugfixes:
- cryptography backend - improve Unicode handling for Python 2 (https://github.com/ansible-collections/community.crypto/pull/313).
release_summary: Regular bugfix release.
fragments:
- 1.9.6.yml
- 313-unicode-names.yml
release_date: '2021-10-30'
1.9.7:
changes:
bugfixes:
- acme_certificate - avoid passing multiple certificates to ``cryptography``'s
X.509 certificate loader when ``fullchain_dest`` is used (https://github.com/ansible-collections/community.crypto/pull/324).
- get_certificate, openssl_csr_info, x509_certificate_info - add fallback code
for extension parsing that works with cryptography 36.0.0 and newer. This
code re-serializes de-serialized extensions and thus can return slightly different
values if the extension in the original CSR resp. certificate was not canonicalized
correctly. This code is currently used as a fallback if the existing code
stops working, but we will switch it to be the main code in a future release
(https://github.com/ansible-collections/community.crypto/pull/331).
- luks_device - now also runs a built-in LUKS signature cleaner on ``state=absent``
to make sure that also the secondary LUKS2 header is wiped when older versions
of wipefs are used (https://github.com/ansible-collections/community.crypto/issues/326,
https://github.com/ansible-collections/community.crypto/pull/327).
- openssl_pkcs12 - use new PKCS#12 deserialization infrastructure from cryptography
36.0.0 if available (https://github.com/ansible-collections/community.crypto/pull/302).
minor_changes:
- acme_* modules - fix usage of ``fetch_url`` with changes in latest ansible-core
``devel`` branch (https://github.com/ansible-collections/community.crypto/pull/339).
release_summary: Bugfix release with extra forward compatibility for newer versions
of cryptography.
fragments:
- 1.9.7.yml
- 302-openssl_pkcs12-cryptography-36.0.0.yml
- 324-acme_certificate-fullchain.yml
- 327-luks_device-wipe.yml
- 331-cryptography-extensions.yml
- fetch_url-devel.yml
release_date: '2021-11-22'

View File

@@ -1 +0,0 @@
release_summary: Bugfix release to fix the changelog. No other change compared to 1.9.0.

View File

@@ -1,6 +1,6 @@
namespace: community namespace: community
name: crypto name: crypto
version: 1.9.2 version: 1.9.7
readme: README.md readme: README.md
authors: authors:
- Ansible (github.com/ansible) - Ansible (github.com/ansible)

View File

@@ -457,8 +457,8 @@ options:
- Time will always be interpreted as UTC. - Time will always be interpreted as UTC.
- Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer - Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer
+ C([w | d | h | m | s]) (e.g. C(+32w1d2h). + 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. - If this value is not specified, the certificate will start being valid from now.
- Note that this value is B(not used to determine whether an existing certificate should be regenerated).
- This is only used by the C(ownca) provider. - This is only used by the C(ownca) provider.
type: str type: str
default: +0s default: +0s
@@ -470,8 +470,8 @@ options:
- Time will always be interpreted as UTC. - Time will always be interpreted as UTC.
- Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer - Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer
+ C([w | d | h | m | s]) (e.g. C(+32w1d2h). + 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. - If this value is not specified, the certificate will stop being valid 10 years from now.
- Note that this value is B(not used to determine whether an existing certificate should be regenerated).
- This is only used by the C(ownca) provider. - This is only used by the C(ownca) provider.
- On macOS 10.15 and onwards, TLS server certificates must have a validity period of 825 days or fewer. - On macOS 10.15 and onwards, TLS server certificates must have a validity period of 825 days or fewer.
Please see U(https://support.apple.com/en-us/HT210176) for more details. Please see U(https://support.apple.com/en-us/HT210176) for more details.
@@ -548,8 +548,8 @@ options:
- Time will always be interpreted as UTC. - Time will always be interpreted as UTC.
- Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer - Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer
+ C([w | d | h | m | s]) (e.g. C(+32w1d2h). + 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. - If this value is not specified, the certificate will start being valid from now.
- Note that this value is B(not used to determine whether an existing certificate should be regenerated).
- This is only used by the C(selfsigned) provider. - This is only used by the C(selfsigned) provider.
type: str type: str
default: +0s default: +0s
@@ -562,8 +562,8 @@ options:
- Time will always be interpreted as UTC. - Time will always be interpreted as UTC.
- Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer - Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer
+ C([w | d | h | m | s]) (e.g. C(+32w1d2h). + 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. - If this value is not specified, the certificate will stop being valid 10 years from now.
- Note that this value is B(not used to determine whether an existing certificate should be regenerated).
- This is only used by the C(selfsigned) provider. - This is only used by the C(selfsigned) provider.
- On macOS 10.15 and onwards, TLS server certificates must have a validity period of 825 days or fewer. - On macOS 10.15 and onwards, TLS server certificates must have a validity period of 825 days or fewer.
Please see U(https://support.apple.com/en-us/HT210176) for more details. Please see U(https://support.apple.com/en-us/HT210176) for more details.

View File

@@ -227,12 +227,11 @@ options:
description: description:
- The authority key identifier as a hex string, where two bytes are separated by colons. - The authority key identifier as a hex string, where two bytes are separated by colons.
- "Example: C(00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22:33)" - "Example: C(00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22:33)"
- If specified, I(authority_cert_issuer) must also be specified.
- "Please note that commercial CAs ignore this value, respectively use a value of their - "Please note that commercial CAs ignore this value, respectively use a value of their
own choice. Specifying this option is mostly useful for self-signed certificates own choice. Specifying this option is mostly useful for self-signed certificates
or for own CAs." or for own CAs."
- Note that this is only supported if the C(cryptography) backend is used! - Note that this is only supported if the C(cryptography) backend is used!
- The C(AuthorityKeyIdentifier) will only be added if at least one of I(authority_key_identifier), - The C(AuthorityKeyIdentifier) extension will only be added if at least one of I(authority_key_identifier),
I(authority_cert_issuer) and I(authority_cert_serial_number) is specified. I(authority_cert_issuer) and I(authority_cert_serial_number) is specified.
type: str type: str
authority_cert_issuer: authority_cert_issuer:
@@ -241,23 +240,24 @@ options:
- Values must be prefixed by their options. (i.e., C(email), C(URI), C(DNS), C(RID), C(IP), C(dirName), - Values must 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) C(otherName) and the ones specific to your CA)
- "Example: C(DNS:ca.example.org)" - "Example: C(DNS:ca.example.org)"
- If specified, I(authority_key_identifier) must also be specified. - If specified, I(authority_cert_serial_number) must also be specified.
- "Please note that commercial CAs ignore this value, respectively use a value of their - "Please note that commercial CAs ignore this value, respectively use a value of their
own choice. Specifying this option is mostly useful for self-signed certificates own choice. Specifying this option is mostly useful for self-signed certificates
or for own CAs." or for own CAs."
- Note that this is only supported if the C(cryptography) backend is used! - Note that this is only supported if the C(cryptography) backend is used!
- The C(AuthorityKeyIdentifier) will only be added if at least one of I(authority_key_identifier), - The C(AuthorityKeyIdentifier) extension will only be added if at least one of I(authority_key_identifier),
I(authority_cert_issuer) and I(authority_cert_serial_number) is specified. I(authority_cert_issuer) and I(authority_cert_serial_number) is specified.
type: list type: list
elements: str elements: str
authority_cert_serial_number: authority_cert_serial_number:
description: description:
- The authority cert serial number. - The authority cert serial number.
- If specified, I(authority_cert_issuer) must also be specified.
- Note that this is only supported if the C(cryptography) backend is used! - Note that this is only supported if the C(cryptography) backend is used!
- "Please note that commercial CAs ignore this value, respectively use a value of their - "Please note that commercial CAs ignore this value, respectively use a value of their
own choice. Specifying this option is mostly useful for self-signed certificates own choice. Specifying this option is mostly useful for self-signed certificates
or for own CAs." or for own CAs."
- The C(AuthorityKeyIdentifier) will only be added if at least one of I(authority_key_identifier), - The C(AuthorityKeyIdentifier) extension will only be added if at least one of I(authority_key_identifier),
I(authority_cert_issuer) and I(authority_cert_serial_number) is specified. I(authority_cert_issuer) and I(authority_cert_serial_number) is specified.
type: int type: int
crl_distribution_points: crl_distribution_points:

View File

@@ -14,8 +14,9 @@ import json
import locale import locale
from ansible.module_utils.basic import missing_required_lib from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.urls import fetch_url
from ansible.module_utils.common.text.converters import to_bytes from ansible.module_utils.common.text.converters import to_bytes
from ansible.module_utils.urls import fetch_url
from ansible.module_utils.six import PY3
from ansible_collections.community.crypto.plugins.module_utils.acme.backend_openssl_cli import ( from ansible_collections.community.crypto.plugins.module_utils.acme.backend_openssl_cli import (
OpenSSLCLIBackend, OpenSSLCLIBackend,
@@ -228,9 +229,14 @@ class ACMEClient(object):
resp, info = fetch_url(self.module, url, data=data, headers=headers, method='POST') resp, info = fetch_url(self.module, url, data=data, headers=headers, method='POST')
_assert_fetch_url_success(self.module, resp, info) _assert_fetch_url_success(self.module, resp, info)
result = {} result = {}
try: try:
# In Python 2, reading from a closed response yields a TypeError.
# In Python 3, read() simply returns ''
if PY3 and resp.closed:
raise TypeError
content = resp.read() content = resp.read()
except AttributeError: except (AttributeError, TypeError):
content = info.pop('body', None) content = info.pop('body', None)
if content or not parse_json_result: if content or not parse_json_result:
@@ -284,8 +290,12 @@ class ACMEClient(object):
_assert_fetch_url_success(self.module, resp, info) _assert_fetch_url_success(self.module, resp, info)
try: try:
# In Python 2, reading from a closed response yields a TypeError.
# In Python 3, read() simply returns ''
if PY3 and resp.closed:
raise TypeError
content = resp.read() content = resp.read()
except AttributeError: except (AttributeError, TypeError):
content = info.pop('body', None) content = info.pop('body', None)
# Process result # Process result

View File

@@ -14,7 +14,7 @@ import datetime
import os import os
import sys import sys
from ansible.module_utils.common.text.converters import to_bytes, to_native from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible_collections.community.crypto.plugins.module_utils.acme.backends import ( from ansible_collections.community.crypto.plugins.module_utils.acme.backends import (
CryptoBackend, CryptoBackend,
@@ -41,6 +41,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp
cryptography_name_to_oid, cryptography_name_to_oid,
) )
from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import (
extract_first_pem,
)
try: try:
import cryptography import cryptography
import cryptography.hazmat.backends import cryptography.hazmat.backends
@@ -357,6 +361,9 @@ class CryptographyBackend(CryptoBackend):
if cert_content is None: if cert_content is None:
return -1 return -1
# Make sure we have at most one PEM. Otherwise cryptography 36.0.0 will barf.
cert_content = to_bytes(extract_first_pem(to_text(cert_content)) or '')
try: try:
cert = cryptography.x509.load_pem_x509_certificate(cert_content, _cryptography_backend) cert = cryptography.x509.load_pem_x509_certificate(cert_content, _cryptography_backend)
except Exception as e: except Exception as e:

View File

@@ -230,7 +230,7 @@ class OpenSSLCLIBackend(CryptoBackend):
filename = csr_filename filename = csr_filename
data = None data = None
if csr_content is not None: if csr_content is not None:
filename = '-' filename = '/dev/stdin'
data = csr_content.encode('utf-8') data = csr_content.encode('utf-8')
openssl_csr_cmd = [self.openssl_binary, "req", "-in", filename, "-noout", "-text"] openssl_csr_cmd = [self.openssl_binary, "req", "-in", filename, "-noout", "-text"]
@@ -267,7 +267,7 @@ class OpenSSLCLIBackend(CryptoBackend):
filename = cert_filename filename = cert_filename
data = None data = None
if cert_content is not None: if cert_content is not None:
filename = '-' filename = '/dev/stdin'
data = cert_content.encode('utf-8') data = cert_content.encode('utf-8')
cert_filename_suffix = '' cert_filename_suffix = ''
elif cert_filename is not None: elif cert_filename is not None:

View File

@@ -7,8 +7,8 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
from ansible.module_utils.six import binary_type
from ansible.module_utils.common.text.converters import to_text from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.six import binary_type, PY3
def format_error_problem(problem, subproblem_prefix=''): def format_error_problem(problem, subproblem_prefix=''):
@@ -52,8 +52,12 @@ class ACMEProtocolException(ModuleFailException):
# Try to get hold of content, if response is given and content is not provided # Try to get hold of content, if response is given and content is not provided
if content is None and content_json is None and response is not None: if content is None and content_json is None and response is not None:
try: try:
# In Python 2, reading from a closed response yields a TypeError.
# In Python 3, read() simply returns ''
if PY3 and response.closed:
raise TypeError
content = response.read() content = response.read()
except AttributeError: except (AttributeError, TypeError):
content = info.pop('body', None) content = info.pop('body', None)
# Make sure that content_json is None or a dictionary # Make sure that content_json is None or a dictionary

View File

@@ -20,6 +20,10 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
# WARNING: this function no longer works with cryptography 35.0.0 and newer!
# It must **ONLY** be used in compatibility code for older
# cryptography versions!
def obj2txt(openssl_lib, openssl_ffi, obj): def obj2txt(openssl_lib, openssl_ffi, obj):
# Set to 80 on the recommendation of # Set to 80 on the recommendation of
# https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values # https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values

View File

@@ -23,12 +23,15 @@ import base64
import binascii import binascii
import re import re
from distutils.version import LooseVersion
from ansible.module_utils.common.text.converters import to_text, to_bytes from ansible.module_utils.common.text.converters import to_text, to_bytes
from ._asn1 import serialize_asn1_string_as_der from ._asn1 import serialize_asn1_string_as_der
try: try:
import cryptography import cryptography
from cryptography import x509 from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import serialization
import ipaddress import ipaddress
except ImportError: except ImportError:
@@ -44,6 +47,15 @@ except ImportError:
# Error handled in the calling module. # Error handled in the calling module.
_load_key_and_certificates = None _load_key_and_certificates = None
try:
# This is a separate try/except since this is only present in cryptography 36.0.0 or newer
from cryptography.hazmat.primitives.serialization.pkcs12 import (
load_pkcs12 as _load_pkcs12,
)
except ImportError:
# Error handled in the calling module.
_load_pkcs12 = None
from .basic import ( from .basic import (
CRYPTOGRAPHY_HAS_ED25519, CRYPTOGRAPHY_HAS_ED25519,
CRYPTOGRAPHY_HAS_ED448, CRYPTOGRAPHY_HAS_ED448,
@@ -64,60 +76,114 @@ DOTTED_OID = re.compile(r'^\d+(?:\.\d+)+$')
def cryptography_get_extensions_from_cert(cert): def cryptography_get_extensions_from_cert(cert):
# Since cryptography won't give us the DER value for an extension
# (that is only stored for unrecognized extensions), we have to re-do
# the extension parsing outselves.
result = dict() result = dict()
backend = cert._backend try:
x509_obj = cert._x509 # Since cryptography won't give us the DER value for an extension
# (that is only stored for unrecognized extensions), we have to re-do
# the extension parsing outselves.
backend = default_backend()
try:
# For certain old versions of cryptography, backend is a MultiBackend object,
# which has no _lib attribute. In that case, revert to the old approach.
backend._lib
except AttributeError:
backend = cert._backend
x509_obj = cert._x509
# With cryptography 35.0.0, we can no longer use obj2txt. Unfortunately it still does
# not allow to get the raw value of an extension, so we have to use this ugly hack:
exts = list(cert.extensions)
for i in range(backend._lib.X509_get_ext_count(x509_obj)):
ext = backend._lib.X509_get_ext(x509_obj, i)
if ext == backend._ffi.NULL:
continue
crit = backend._lib.X509_EXTENSION_get_critical(ext)
data = backend._lib.X509_EXTENSION_get_data(ext)
backend.openssl_assert(data != backend._ffi.NULL)
der = backend._ffi.buffer(data.data, data.length)[:]
entry = dict(
critical=(crit == 1),
value=base64.b64encode(der),
)
try:
oid = obj2txt(backend._lib, backend._ffi, backend._lib.X509_EXTENSION_get_object(ext))
except AttributeError:
oid = exts[i].oid.dotted_string
result[oid] = entry
except Exception:
# In case the above method breaks, we likely have cryptography 36.0.0 or newer.
# Use it's public_bytes() feature in that case. We will later switch this around
# so that this code will be the default, but for now this will act as a fallback
# since it will re-serialize de-serialized data, which can be different (if the
# original data was not canonicalized) from what was contained in the certificate.
for ext in cert.extensions:
result[ext.oid.dotted_string] = dict(
critical=ext.critical,
value=base64.b64encode(ext.value.public_bytes()),
)
for i in range(backend._lib.X509_get_ext_count(x509_obj)):
ext = backend._lib.X509_get_ext(x509_obj, i)
if ext == backend._ffi.NULL:
continue
crit = backend._lib.X509_EXTENSION_get_critical(ext)
data = backend._lib.X509_EXTENSION_get_data(ext)
backend.openssl_assert(data != backend._ffi.NULL)
der = backend._ffi.buffer(data.data, data.length)[:]
entry = dict(
critical=(crit == 1),
value=base64.b64encode(der),
)
oid = obj2txt(backend._lib, backend._ffi, backend._lib.X509_EXTENSION_get_object(ext))
result[oid] = entry
return result return result
def cryptography_get_extensions_from_csr(csr): def cryptography_get_extensions_from_csr(csr):
# Since cryptography won't give us the DER value for an extension
# (that is only stored for unrecognized extensions), we have to re-do
# the extension parsing outselves.
result = dict() result = dict()
backend = csr._backend try:
# Since cryptography won't give us the DER value for an extension
# (that is only stored for unrecognized extensions), we have to re-do
# the extension parsing outselves.
backend = default_backend()
try:
# For certain old versions of cryptography, backend is a MultiBackend object,
# which has no _lib attribute. In that case, revert to the old approach.
backend._lib
except AttributeError:
backend = csr._backend
extensions = backend._lib.X509_REQ_get_extensions(csr._x509_req) extensions = backend._lib.X509_REQ_get_extensions(csr._x509_req)
extensions = backend._ffi.gc( extensions = backend._ffi.gc(
extensions, extensions,
lambda ext: backend._lib.sk_X509_EXTENSION_pop_free( lambda ext: backend._lib.sk_X509_EXTENSION_pop_free(
ext, ext,
backend._ffi.addressof(backend._lib._original_lib, "X509_EXTENSION_free") backend._ffi.addressof(backend._lib._original_lib, "X509_EXTENSION_free")
)
) )
)
for i in range(backend._lib.sk_X509_EXTENSION_num(extensions)): # With cryptography 35.0.0, we can no longer use obj2txt. Unfortunately it still does
ext = backend._lib.sk_X509_EXTENSION_value(extensions, i) # not allow to get the raw value of an extension, so we have to use this ugly hack:
if ext == backend._ffi.NULL: exts = list(csr.extensions)
continue
crit = backend._lib.X509_EXTENSION_get_critical(ext) for i in range(backend._lib.sk_X509_EXTENSION_num(extensions)):
data = backend._lib.X509_EXTENSION_get_data(ext) ext = backend._lib.sk_X509_EXTENSION_value(extensions, i)
backend.openssl_assert(data != backend._ffi.NULL) if ext == backend._ffi.NULL:
der = backend._ffi.buffer(data.data, data.length)[:] continue
entry = dict( crit = backend._lib.X509_EXTENSION_get_critical(ext)
critical=(crit == 1), data = backend._lib.X509_EXTENSION_get_data(ext)
value=base64.b64encode(der), backend.openssl_assert(data != backend._ffi.NULL)
) der = backend._ffi.buffer(data.data, data.length)[:]
oid = obj2txt(backend._lib, backend._ffi, backend._lib.X509_EXTENSION_get_object(ext)) entry = dict(
result[oid] = entry critical=(crit == 1),
value=base64.b64encode(der),
)
try:
oid = obj2txt(backend._lib, backend._ffi, backend._lib.X509_EXTENSION_get_object(ext))
except AttributeError:
oid = exts[i].oid.dotted_string
result[oid] = entry
except Exception:
# In case the above method breaks, we likely have cryptography 36.0.0 or newer.
# Use it's public_bytes() feature in that case. We will later switch this around
# so that this code will be the default, but for now this will act as a fallback
# since it will re-serialize de-serialized data, which can be different (if the
# original data was not canonicalized) from what was contained in the CSR.
for ext in csr.extensions:
result[ext.oid.dotted_string] = dict(
critical=ext.critical,
value=base64.b64encode(ext.value.public_bytes()),
)
return result return result
@@ -280,11 +346,11 @@ def _dn_escape_value(value):
''' '''
Escape Distinguished Name's attribute value. Escape Distinguished Name's attribute value.
''' '''
value = value.replace('\\', '\\\\') value = value.replace(u'\\', u'\\\\')
for ch in [',', '#', '+', '<', '>', ';', '"', '=', '/']: for ch in [u',', u'#', u'+', u'<', u'>', u';', u'"', u'=', u'/']:
value = value.replace(ch, '\\%s' % ch) value = value.replace(ch, u'\\%s' % ch)
if value.startswith(' '): if value.startswith(u' '):
value = r'\ ' + value[1:] value = u'\\ ' + value[1:]
return value return value
@@ -294,24 +360,24 @@ def cryptography_decode_name(name):
Raises an OpenSSLObjectError if the name is not supported. Raises an OpenSSLObjectError if the name is not supported.
''' '''
if isinstance(name, x509.DNSName): if isinstance(name, x509.DNSName):
return 'DNS:{0}'.format(name.value) return u'DNS:{0}'.format(name.value)
if isinstance(name, x509.IPAddress): if isinstance(name, x509.IPAddress):
if isinstance(name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network)): if isinstance(name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network)):
return 'IP:{0}/{1}'.format(name.value.network_address.compressed, name.value.prefixlen) return u'IP:{0}/{1}'.format(name.value.network_address.compressed, name.value.prefixlen)
return 'IP:{0}'.format(name.value.compressed) return u'IP:{0}'.format(name.value.compressed)
if isinstance(name, x509.RFC822Name): if isinstance(name, x509.RFC822Name):
return 'email:{0}'.format(name.value) return u'email:{0}'.format(name.value)
if isinstance(name, x509.UniformResourceIdentifier): if isinstance(name, x509.UniformResourceIdentifier):
return 'URI:{0}'.format(name.value) return u'URI:{0}'.format(name.value)
if isinstance(name, x509.DirectoryName): if isinstance(name, x509.DirectoryName):
return 'dirName:' + ''.join([ return u'dirName:' + u''.join([
'/{0}={1}'.format(cryptography_oid_to_name(attribute.oid, short=True), _dn_escape_value(attribute.value)) u'/{0}={1}'.format(to_text(cryptography_oid_to_name(attribute.oid, short=True)), _dn_escape_value(attribute.value))
for attribute in name.value for attribute in name.value
]) ])
if isinstance(name, x509.RegisteredID): if isinstance(name, x509.RegisteredID):
return 'RID:{0}'.format(name.value.dotted_string) return u'RID:{0}'.format(name.value.dotted_string)
if isinstance(name, x509.OtherName): if isinstance(name, x509.OtherName):
return 'otherName:{0};{1}'.format(name.type_id.dotted_string, _get_hex(name.value)) return u'otherName:{0};{1}'.format(name.type_id.dotted_string, _get_hex(name.value))
raise OpenSSLObjectError('Cannot decode name "{0}"'.format(name)) raise OpenSSLObjectError('Cannot decode name "{0}"'.format(name))
@@ -442,17 +508,74 @@ def cryptography_serial_number_of_cert(cert):
def parse_pkcs12(pkcs12_bytes, passphrase=None): def parse_pkcs12(pkcs12_bytes, passphrase=None):
'''Returns a tuple (private_key, certificate, additional_certificates, friendly_name). '''Returns a tuple (private_key, certificate, additional_certificates, friendly_name).
''' '''
if _load_key_and_certificates is None: if _load_pkcs12 is None and _load_key_and_certificates is None:
raise ValueError('load_key_and_certificates() not present in the current cryptography version') raise ValueError('neither load_pkcs12() nor load_key_and_certificates() present in the current cryptography version')
private_key, certificate, additional_certificates = _load_key_and_certificates(
pkcs12_bytes, to_bytes(passphrase) if passphrase is not None else None) if passphrase is not None:
passphrase = to_bytes(passphrase)
# Main code for cryptography 36.0.0 and forward
if _load_pkcs12 is not None:
return _parse_pkcs12_36_0_0(pkcs12_bytes, passphrase)
if LooseVersion(cryptography.__version__) >= LooseVersion('35.0'):
return _parse_pkcs12_35_0_0(pkcs12_bytes, passphrase)
return _parse_pkcs12_legacy(pkcs12_bytes, passphrase)
def _parse_pkcs12_36_0_0(pkcs12_bytes, passphrase=None):
# Requires cryptography 36.0.0 or newer
pkcs12 = _load_pkcs12(pkcs12_bytes, passphrase)
additional_certificates = [cert.certificate for cert in pkcs12.additional_certs]
private_key = pkcs12.key
certificate = None
friendly_name = None
if pkcs12.cert:
certificate = pkcs12.cert.certificate
friendly_name = pkcs12.cert.friendly_name
return private_key, certificate, additional_certificates, friendly_name
def _parse_pkcs12_35_0_0(pkcs12_bytes, passphrase=None):
# Backwards compatibility code for cryptography 35.x
private_key, certificate, additional_certificates = _load_key_and_certificates(pkcs12_bytes, passphrase)
friendly_name = None friendly_name = None
if certificate: if certificate:
# See https://github.com/pyca/cryptography/issues/5760#issuecomment-842687238 # See https://github.com/pyca/cryptography/issues/5760#issuecomment-842687238
maybe_name = certificate._backend._lib.X509_alias_get0( backend = default_backend()
certificate._x509, certificate._backend._ffi.NULL)
if maybe_name != certificate._backend._ffi.NULL: # This code basically does what load_key_and_certificates() does, but without error-checking.
friendly_name = certificate._backend._ffi.string(maybe_name) # Since load_key_and_certificates succeeded, it should not fail.
pkcs12 = backend._ffi.gc(
backend._lib.d2i_PKCS12_bio(backend._bytes_to_bio(pkcs12_bytes).bio, backend._ffi.NULL),
backend._lib.PKCS12_free)
certificate_x509_ptr = backend._ffi.new("X509 **")
with backend._zeroed_null_terminated_buf(to_bytes(passphrase) if passphrase is not None else None) as passphrase_buffer:
backend._lib.PKCS12_parse(
pkcs12,
passphrase_buffer,
backend._ffi.new("EVP_PKEY **"),
certificate_x509_ptr,
backend._ffi.new("Cryptography_STACK_OF_X509 **"))
if certificate_x509_ptr[0] != backend._ffi.NULL:
maybe_name = backend._lib.X509_alias_get0(certificate_x509_ptr[0], backend._ffi.NULL)
if maybe_name != backend._ffi.NULL:
friendly_name = backend._ffi.string(maybe_name)
return private_key, certificate, additional_certificates, friendly_name return private_key, certificate, additional_certificates, friendly_name
def _parse_pkcs12_legacy(pkcs12_bytes, passphrase=None):
# Backwards compatibility code for cryptography < 35.0.0
private_key, certificate, additional_certificates = _load_key_and_certificates(pkcs12_bytes, passphrase)
friendly_name = None
if certificate:
# See https://github.com/pyca/cryptography/issues/5760#issuecomment-842687238
backend = certificate._backend
maybe_name = backend._lib.X509_alias_get0(certificate._x509, backend._ffi.NULL)
if maybe_name != backend._ffi.NULL:
friendly_name = backend._ffi.string(maybe_name)
return private_key, certificate, additional_certificates, friendly_name

View File

@@ -592,7 +592,7 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
def _check_csr(self): def _check_csr(self):
"""Check whether provided parameters, assuming self.existing_csr and self.privatekey have been populated.""" """Check whether provided parameters, assuming self.existing_csr and self.privatekey have been populated."""
def _check_subject(csr): def _check_subject(csr):
subject = [(cryptography_name_to_oid(entry[0]), entry[1]) for entry in self.subject] subject = [(cryptography_name_to_oid(entry[0]), to_text(entry[1])) for entry in self.subject]
current_subject = [(sub.oid, sub.value) for sub in csr.subject] current_subject = [(sub.oid, sub.value) for sub in csr.subject]
return set(subject) == set(current_subject) return set(subject) == set(current_subject)
@@ -604,8 +604,8 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
def _check_subjectAltName(extensions): def _check_subjectAltName(extensions):
current_altnames_ext = _find_extension(extensions, cryptography.x509.SubjectAlternativeName) current_altnames_ext = _find_extension(extensions, cryptography.x509.SubjectAlternativeName)
current_altnames = [str(altname) for altname in current_altnames_ext.value] if current_altnames_ext else [] current_altnames = [to_text(altname) for altname in current_altnames_ext.value] if current_altnames_ext else []
altnames = [str(cryptography_get_name(altname)) for altname in self.subjectAltName] if self.subjectAltName else [] altnames = [to_text(cryptography_get_name(altname)) for altname in self.subjectAltName] if self.subjectAltName else []
if set(altnames) != set(current_altnames): if set(altnames) != set(current_altnames):
return False return False
if altnames: if altnames:
@@ -678,10 +678,10 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
def _check_nameConstraints(extensions): def _check_nameConstraints(extensions):
current_nc_ext = _find_extension(extensions, cryptography.x509.NameConstraints) current_nc_ext = _find_extension(extensions, cryptography.x509.NameConstraints)
current_nc_perm = [str(altname) for altname in current_nc_ext.value.permitted_subtrees] if current_nc_ext else [] current_nc_perm = [to_text(altname) for altname in current_nc_ext.value.permitted_subtrees] if current_nc_ext else []
current_nc_excl = [str(altname) for altname in current_nc_ext.value.excluded_subtrees] if current_nc_ext else [] current_nc_excl = [to_text(altname) for altname in current_nc_ext.value.excluded_subtrees] if current_nc_ext else []
nc_perm = [str(cryptography_get_name(altname, 'name constraints permitted')) for altname in self.name_constraints_permitted] nc_perm = [to_text(cryptography_get_name(altname, 'name constraints permitted')) for altname in self.name_constraints_permitted]
nc_excl = [str(cryptography_get_name(altname, 'name constraints excluded')) for altname in self.name_constraints_excluded] nc_excl = [to_text(cryptography_get_name(altname, 'name constraints excluded')) for altname in self.name_constraints_excluded]
if set(nc_perm) != set(current_nc_perm) or set(nc_excl) != set(current_nc_excl): if set(nc_perm) != set(current_nc_perm) or set(nc_excl) != set(current_nc_excl):
return False return False
if nc_perm or nc_excl: if nc_perm or nc_excl:
@@ -710,9 +710,9 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
aci = None aci = None
csr_aci = None csr_aci = None
if self.authority_cert_issuer is not None: if self.authority_cert_issuer is not None:
aci = [str(cryptography_get_name(n, 'authority cert issuer')) for n in self.authority_cert_issuer] aci = [to_text(cryptography_get_name(n, 'authority cert issuer')) for n in self.authority_cert_issuer]
if ext.value.authority_cert_issuer is not None: if ext.value.authority_cert_issuer is not None:
csr_aci = [str(n) for n in ext.value.authority_cert_issuer] csr_aci = [to_text(n) for n in ext.value.authority_cert_issuer]
return (ext.value.key_identifier == self.authority_key_identifier return (ext.value.key_identifier == self.authority_key_identifier
and csr_aci == aci and csr_aci == aci
and ext.value.authority_cert_serial_number == self.authority_cert_serial_number) and ext.value.authority_cert_serial_number == self.authority_cert_serial_number)

View File

@@ -72,3 +72,13 @@ def split_pem_list(text, keep_inbetween=False):
result.append(''.join(current)) result.append(''.join(current))
current = [] if keep_inbetween else None current = [] if keep_inbetween else None
return result return result
def extract_first_pem(text):
'''
Given one PEM or multiple concatenated PEM objects, return only the first one, or None if there is none.
'''
all_pems = split_pem_list(text)
if not all_pems:
return None
return all_pems[0]

View File

@@ -21,10 +21,12 @@ __metaclass__ = type
import base64 import base64
from ansible.module_utils.common.text.converters import to_bytes, to_text from ansible.module_utils.common.text.converters import to_bytes, to_text, to_native
from ansible_collections.community.crypto.plugins.module_utils.compat import ipaddress as compat_ipaddress from ansible_collections.community.crypto.plugins.module_utils.compat import ipaddress as compat_ipaddress
from ._objects import OID_LOOKUP
try: try:
import OpenSSL import OpenSSL
except ImportError: except ImportError:
@@ -87,18 +89,25 @@ def pyopenssl_get_extensions_from_cert(cert):
critical=bool(ext.get_critical()), critical=bool(ext.get_critical()),
value=base64.b64encode(ext.get_data()), value=base64.b64encode(ext.get_data()),
) )
oid = obj2txt( try:
OpenSSL._util.lib, oid = obj2txt(
OpenSSL._util.ffi, OpenSSL._util.lib,
OpenSSL._util.lib.X509_EXTENSION_get_object(ext._extension) OpenSSL._util.ffi,
) OpenSSL._util.lib.X509_EXTENSION_get_object(ext._extension)
# This could also be done a bit simpler: )
# # This could also be done a bit simpler:
# oid = obj2txt(OpenSSL._util.lib, OpenSSL._util.ffi, OpenSSL._util.lib.OBJ_nid2obj(ext._nid)) #
# # oid = obj2txt(OpenSSL._util.lib, OpenSSL._util.ffi, OpenSSL._util.lib.OBJ_nid2obj(ext._nid))
# Unfortunately this gives the wrong result in case the linked OpenSSL #
# doesn't know the OID. That's why we have to get the OID dotted string # Unfortunately this gives the wrong result in case the linked OpenSSL
# similarly to how cryptography does it. # doesn't know the OID. That's why we have to get the OID dotted string
# similarly to how cryptography does it.
except AttributeError:
# When PyOpenSSL is used with cryptography >= 35.0.0, obj2txt cannot be used.
# We try to figure out the OID with our internal lookup table, and if we fail,
# we use the short name OpenSSL returns.
oid = to_native(ext.get_short_name())
oid = OID_LOOKUP.get(oid, oid)
result[oid] = entry result[oid] = entry
return result return result
@@ -113,18 +122,25 @@ def pyopenssl_get_extensions_from_csr(csr):
critical=bool(ext.get_critical()), critical=bool(ext.get_critical()),
value=base64.b64encode(ext.get_data()), value=base64.b64encode(ext.get_data()),
) )
oid = obj2txt( try:
OpenSSL._util.lib, oid = obj2txt(
OpenSSL._util.ffi, OpenSSL._util.lib,
OpenSSL._util.lib.X509_EXTENSION_get_object(ext._extension) OpenSSL._util.ffi,
) OpenSSL._util.lib.X509_EXTENSION_get_object(ext._extension)
# This could also be done a bit simpler: )
# # This could also be done a bit simpler:
# oid = obj2txt(OpenSSL._util.lib, OpenSSL._util.ffi, OpenSSL._util.lib.OBJ_nid2obj(ext._nid)) #
# # oid = obj2txt(OpenSSL._util.lib, OpenSSL._util.ffi, OpenSSL._util.lib.OBJ_nid2obj(ext._nid))
# Unfortunately this gives the wrong result in case the linked OpenSSL #
# doesn't know the OID. That's why we have to get the OID dotted string # Unfortunately this gives the wrong result in case the linked OpenSSL
# similarly to how cryptography does it. # doesn't know the OID. That's why we have to get the OID dotted string
# similarly to how cryptography does it.
except AttributeError:
# When PyOpenSSL is used with cryptography >= 35.0.0, obj2txt cannot be used.
# We try to figure out the OID with our internal lookup table, and if we fail,
# we use the short name OpenSSL returns.
oid = to_native(ext.get_short_name())
oid = OID_LOOKUP.get(oid, oid)
result[oid] = entry result[oid] = entry
return result return result

View File

@@ -160,7 +160,8 @@ class KeygenCommand(object):
self._run_command = module.run_command self._run_command = module.run_command
def generate_certificate(self, certificate_path, identifier, options, pkcs11_provider, principals, def generate_certificate(self, certificate_path, identifier, options, pkcs11_provider, principals,
serial_number, signing_key_path, type, time_parameters, use_agent, **kwargs): serial_number, signature_algorithm, signing_key_path, type,
time_parameters, use_agent, **kwargs):
args = [self._bin_path, '-s', signing_key_path, '-P', '', '-I', identifier] args = [self._bin_path, '-s', signing_key_path, '-P', '', '-I', identifier]
if options: if options:
@@ -178,6 +179,8 @@ class KeygenCommand(object):
args.extend(['-U']) args.extend(['-U'])
if time_parameters.validity_string: if time_parameters.validity_string:
args.extend(['-V', time_parameters.validity_string]) args.extend(['-V', time_parameters.validity_string])
if signature_algorithm:
args.extend(['-t', signature_algorithm])
args.append(certificate_path) args.append(certificate_path)
return self._run_command(args, **kwargs) return self._run_command(args, **kwargs)

View File

@@ -555,6 +555,11 @@ class OpensshCertificate(object):
def signing_key(self): def signing_key(self):
return to_text(self._cert_info.signing_key_fingerprint()) return to_text(self._cert_info.signing_key_fingerprint())
@property
def signature_type(self):
signature_data = OpensshParser.signature_data(self.signature)
return to_text(signature_data['signature_type'])
@staticmethod @staticmethod
def _parse_cert_info(pub_key_type, parser): def _parse_cert_info(pub_key_type, parser):
cert_info = get_cert_info_object(pub_key_type) cert_info = get_cert_info_object(pub_key_type)

View File

@@ -201,8 +201,9 @@ class OpensshParser(object):
signature_blob = parser.string() signature_blob = parser.string()
blob_parser = cls(signature_blob) blob_parser = cls(signature_blob)
if signature_type == b'ssh-rsa': if signature_type in (b'ssh-rsa', b'rsa-sha2-256', b'rsa-sha2-512'):
# https://datatracker.ietf.org/doc/html/rfc4253#section-6.6 # https://datatracker.ietf.org/doc/html/rfc4253#section-6.6
# https://datatracker.ietf.org/doc/html/rfc8332#section-3
signature_data['s'] = cls._big_int(signature_blob, "big") signature_data['s'] = cls._big_int(signature_blob, "big")
elif signature_type == b'ssh-dss': elif signature_type == b'ssh-dss':
# https://datatracker.ietf.org/doc/html/rfc4253#section-6.6 # https://datatracker.ietf.org/doc/html/rfc4253#section-6.6

View File

@@ -202,7 +202,10 @@ def main():
), ),
) )
if not HAS_CRYPTOGRAPHY: if not HAS_CRYPTOGRAPHY:
module.fail_json(msg=missing_required_lib('cryptography >= 1.3'), exception=CRYPTOGRAPHY_IMP_ERR) # Some callbacks die when exception is provided with value None
if CRYPTOGRAPHY_IMP_ERR:
module.fail_json(msg=missing_required_lib('cryptography >= 1.3'), exception=CRYPTOGRAPHY_IMP_ERR)
module.fail_json(msg=missing_required_lib('cryptography >= 1.3'))
try: try:
# Get parameters # Get parameters

View File

@@ -356,6 +356,34 @@ LUKS_NAME_REGEX = re.compile(r'\s*crypt\s+([^\s]*)\s*')
LUKS_DEVICE_REGEX = re.compile(r'\s*device:\s+([^\s]*)\s*') LUKS_DEVICE_REGEX = re.compile(r'\s*device:\s+([^\s]*)\s*')
# See https://gitlab.com/cryptsetup/cryptsetup/-/wikis/LUKS-standard/on-disk-format.pdf
LUKS_HEADER = b'LUKS\xba\xbe'
LUKS_HEADER_L = 6
# See https://gitlab.com/cryptsetup/LUKS2-docs/-/blob/master/luks2_doc_wip.pdf
LUKS2_HEADER_OFFSETS = [0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000]
LUKS2_HEADER2 = b'SKUL\xba\xbe'
def wipe_luks_headers(device):
wipe_offsets = []
with open(device, 'rb') as f:
# f.seek(0)
data = f.read(LUKS_HEADER_L)
if data == LUKS_HEADER:
wipe_offsets.append(0)
for offset in LUKS2_HEADER_OFFSETS:
f.seek(offset)
data = f.read(LUKS_HEADER_L)
if data == LUKS2_HEADER2:
wipe_offsets.append(offset)
if wipe_offsets:
with open(device, 'wb') as f:
for offset in wipe_offsets:
f.seek(offset)
f.write(b'\x00\x00\x00\x00\x00\x00')
class Handler(object): class Handler(object):
def __init__(self, module): def __init__(self, module):
@@ -515,9 +543,17 @@ class CryptHandler(Handler):
self.run_luks_close(name) self.run_luks_close(name)
result = self._run_command([wipefs_bin, '--all', device]) result = self._run_command([wipefs_bin, '--all', device])
if result[RETURN_CODE] != 0: if result[RETURN_CODE] != 0:
raise ValueError('Error while wiping luks container %s: %s' raise ValueError('Error while wiping LUKS container signatures for %s: %s'
% (device, result[STDERR])) % (device, result[STDERR]))
# For LUKS2, sometimes both `cryptsetup erase` and `wipefs` do **not**
# erase all LUKS signatures (they seem to miss the second header). That's
# why we do it ourselves here.
try:
wipe_luks_headers(device)
except Exception as exc:
raise ValueError('Error while wiping LUKS container signatures for %s: %s' % (device, exc))
def run_luks_add_key(self, device, keyfile, passphrase, new_keyfile, def run_luks_add_key(self, device, keyfile, passphrase, new_keyfile,
new_passphrase, pbkdf): new_passphrase, pbkdf):
''' Add new key from a keyfile or passphrase to given 'device'; ''' Add new key from a keyfile or passphrase to given 'device';

View File

@@ -49,7 +49,7 @@ options:
- When C(fail) the task will fail if a certificate already exists at I(path) and does not - When C(fail) the task will fail if a certificate already exists at I(path) and does not
match the module's options. match the module's options.
- When C(partial_idempotence) an existing certificate will be regenerated based on - When C(partial_idempotence) an existing certificate will be regenerated based on
I(serial), I(type), I(valid_from), I(valid_to), I(valid_at), and I(principals). I(serial), I(signature_algorithm), I(type), I(valid_from), I(valid_to), I(valid_at), and I(principals).
- When C(full_idempotence) I(identifier), I(options), I(public_key), and I(signing_key) - When C(full_idempotence) I(identifier), I(options), I(public_key), and I(signing_key)
are also considered when compared against an existing certificate. are also considered when compared against an existing certificate.
- C(always) is equivalent to I(force=true). - C(always) is equivalent to I(force=true).
@@ -62,6 +62,26 @@ options:
- always - always
default: partial_idempotence default: partial_idempotence
version_added: 1.8.0 version_added: 1.8.0
signature_algorithm:
description:
- As of OpenSSH 8.2 the SHA-1 signature algorithm for RSA keys has been disabled and C(ssh) will refuse
host certificates signed with the SHA-1 algorithm. OpenSSH 8.1 made C(rsa-sha2-512) the default algorithm
when acting as a CA and signing certificates with a RSA key. However, for OpenSSH versions less than 8.1
the SHA-2 signature algorithms, C(rsa-sha2-256) or C(rsa-sha2-512), must be specified using this option
if compatibility with newer C(ssh) clients is required. Conversely if hosts using OpenSSH version 8.2
or greater must remain compatible with C(ssh) clients using OpenSSH less than 7.2, then C(ssh-rsa)
can be used when generating host certificates (a corresponding change to the sshd_config to add C(ssh-rsa)
to the C(CASignatureAlgorithms) keyword is also required).
- Using any value for this option with a non-RSA I(signing_key) will cause this module to fail.
- "Note: OpenSSH versions prior to 7.2 do not support SHA-2 signature algorithms for RSA keys and OpenSSH
versions prior to 7.3 do not support SHA-2 signature algorithms for certificates."
- See U(https://www.openssh.com/txt/release-8.2) for more information.
type: str
choices:
- ssh-rsa
- rsa-sha2-256
- rsa-sha2-512
version_added: 1.10.0
signing_key: signing_key:
description: description:
- The path to the private openssh key that is used for signing the public key in order to generate the certificate. - The path to the private openssh key that is used for signing the public key in order to generate the certificate.
@@ -269,6 +289,7 @@ class Certificate(OpensshModule):
self.public_key = self.module.params['public_key'] self.public_key = self.module.params['public_key']
self.regenerate = self.module.params['regenerate'] if not self.module.params['force'] else 'always' self.regenerate = self.module.params['regenerate'] if not self.module.params['force'] else 'always'
self.serial_number = self.module.params['serial_number'] self.serial_number = self.module.params['serial_number']
self.signature_algorithm = self.module.params['signature_algorithm']
self.signing_key = self.module.params['signing_key'] self.signing_key = self.module.params['signing_key']
self.state = self.module.params['state'] self.state = self.module.params['state']
self.type = self.module.params['type'] self.type = self.module.params['type']
@@ -366,6 +387,7 @@ class Certificate(OpensshModule):
def _is_partially_valid(self): def _is_partially_valid(self):
return all([ return all([
set(self.original_data.principals) == set(self.principals), set(self.original_data.principals) == set(self.principals),
self.original_data.signature_type == self.signature_algorithm if self.signature_algorithm else True,
self.original_data.serial == self.serial_number if self.serial_number is not None else True, self.original_data.serial == self.serial_number if self.serial_number is not None else True,
self.original_data.type == self.type, self.original_data.type == self.type,
self._compare_time_parameters(), self._compare_time_parameters(),
@@ -425,7 +447,7 @@ class Certificate(OpensshModule):
self.ssh_keygen.generate_certificate( self.ssh_keygen.generate_certificate(
key_copy, self.identifier, self.options, self.pkcs11_provider, self.principals, self.serial_number, key_copy, self.identifier, self.options, self.pkcs11_provider, self.principals, self.serial_number,
self.signing_key, self.type, self.time_parameters, self.use_agent, self.signature_algorithm, self.signing_key, self.type, self.time_parameters, self.use_agent,
environ_update=dict(TZ="UTC"), check_rc=True environ_update=dict(TZ="UTC"), check_rc=True
) )
@@ -485,6 +507,8 @@ def get_cert_dict(data):
result = data.to_dict() result = data.to_dict()
result.pop('nonce') result.pop('nonce')
result['signature_algorithm'] = data.signature_type
return result return result
@@ -503,6 +527,7 @@ def main():
default='partial_idempotence', default='partial_idempotence',
choices=['never', 'fail', 'partial_idempotence', 'full_idempotence', 'always'] choices=['never', 'fail', 'partial_idempotence', 'full_idempotence', 'always']
), ),
signature_algorithm=dict(type='str', choices=['ssh-rsa', 'rsa-sha2-256', 'rsa-sha2-512']),
signing_key=dict(type='path'), signing_key=dict(type='path'),
serial_number=dict(type='int'), serial_number=dict(type='int'),
state=dict(type='str', default='present', choices=['absent', 'present']), state=dict(type='str', default='present', choices=['absent', 'present']),

View File

@@ -1,2 +1,14 @@
shippable/cloud/group1 shippable/cloud/group1
cloud/acme cloud/acme
# Since skipping below fails miserably with ansible-core 2.11 and earlier, we have to skip all POSIX tests...
# (https://github.com/ansible/ansible/issues/75711)
# shippable/posix/group1
# Skip all VMs, since we cannot talk to the ACME simulator from these:
# (TODO: remove when ansible-core 2.12 is the earliest version we support)
# skip/aix
# skip/freebsd
# skip/macos
# skip/osx
# skip/rhel

View File

@@ -1,2 +1,3 @@
dependencies: dependencies:
- setup_acme - setup_acme
- setup_remote_tmp_dir

View File

@@ -1,9 +1,9 @@
- block: - block:
- name: Generate account keys - name: Generate account keys
openssl_privatekey: openssl_privatekey:
path: "{{ output_dir }}/{{ item.name }}.pem" path: "{{ remote_tmp_dir }}/{{ item.name }}.pem"
passphrase: "{{ item.pass | default(omit, true) }}" passphrase: "{{ item.pass | default(omit) | default(omit, true) }}"
cipher: "{{ 'auto' if item.pass | default() else omit }}" cipher: "{{ 'auto' if (item.pass | default(false)) else omit }}"
type: ECC type: ECC
curve: secp256r1 curve: secp256r1
force: true force: true
@@ -11,8 +11,8 @@
- name: Parse account keys (to ease debugging some test failures) - name: Parse account keys (to ease debugging some test failures)
openssl_privatekey_info: openssl_privatekey_info:
path: "{{ output_dir }}/{{ item.name }}.pem" path: "{{ remote_tmp_dir }}/{{ item.name }}.pem"
passphrase: "{{ item.pass | default(omit, true) }}" passphrase: "{{ item.pass | default(omit) | default(omit, true) }}"
return_private_key_data: true return_private_key_data: true
loop: "{{ account_keys }}" loop: "{{ account_keys }}"
@@ -28,7 +28,7 @@
- name: Do not try to create account - name: Do not try to create account
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -40,7 +40,7 @@
- name: Create it now (check mode, diff) - name: Create it now (check mode, diff)
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -56,7 +56,7 @@
- name: Create it now - name: Create it now
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -70,7 +70,7 @@
- name: Create it now (idempotent) - name: Create it now (idempotent)
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -81,10 +81,15 @@
- mailto:example@example.org - mailto:example@example.org
register: account_created_idempotent register: account_created_idempotent
- name: Read account key
slurp:
src: '{{ remote_tmp_dir }}/accountkey.pem'
register: slurp
- name: Change email address (check mode, diff) - name: Change email address (check mode, diff)
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_content: "{{ lookup('file', output_dir ~ '/accountkey.pem') }}" account_key_content: "{{ slurp.content | b64decode }}"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -99,7 +104,7 @@
- name: Change email address - name: Change email address
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_content: "{{ lookup('file', output_dir ~ '/accountkey.pem') }}" account_key_content: "{{ slurp.content | b64decode }}"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -112,7 +117,7 @@
- name: Change email address (idempotent) - name: Change email address (idempotent)
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_created.account_uri }}" account_uri: "{{ account_created.account_uri }}"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
@@ -126,7 +131,7 @@
- name: Cannot access account with wrong URI - name: Cannot access account with wrong URI
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_created.account_uri ~ '12345thisdoesnotexist' }}" account_uri: "{{ account_created.account_uri ~ '12345thisdoesnotexist' }}"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
@@ -139,7 +144,7 @@
- name: Clear contact email addresses (check mode, diff) - name: Clear contact email addresses (check mode, diff)
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -153,7 +158,7 @@
- name: Clear contact email addresses - name: Clear contact email addresses
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -165,7 +170,7 @@
- name: Clear contact email addresses (idempotent) - name: Clear contact email addresses (idempotent)
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -177,11 +182,11 @@
- name: Change account key (check mode, diff) - name: Change account key (check mode, diff)
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
new_account_key_src: "{{ output_dir }}/accountkey2.pem" new_account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
new_account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}" new_account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
state: changed_key state: changed_key
contact: contact:
@@ -193,11 +198,11 @@
- name: Change account key - name: Change account key
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
new_account_key_src: "{{ output_dir }}/accountkey2.pem" new_account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
new_account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}" new_account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
state: changed_key state: changed_key
contact: contact:
@@ -207,7 +212,7 @@
- name: Deactivate account (check mode, diff) - name: Deactivate account (check mode, diff)
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey2.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}" account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
@@ -220,7 +225,7 @@
- name: Deactivate account - name: Deactivate account
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey2.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}" account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
@@ -231,7 +236,7 @@
- name: Deactivate account (idempotent) - name: Deactivate account (idempotent)
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey2.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}" account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
@@ -242,7 +247,7 @@
- name: Do not try to create account II - name: Do not try to create account II
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey2.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}" account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
@@ -255,7 +260,7 @@
- name: Do not try to create account III - name: Do not try to create account III
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -267,7 +272,7 @@
- name: Create account with External Account Binding - name: Create account with External Account Binding
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/{{ item.account }}.pem" account_key_src: "{{ remote_tmp_dir }}/{{ item.account }}.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no

View File

@@ -17,12 +17,12 @@
- name: Remove output directory - name: Remove output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: absent state: absent
- name: Re-create output directory - name: Re-create output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: directory state: directory
- block: - block:

View File

@@ -1,2 +1,14 @@
shippable/cloud/group1 shippable/cloud/group1
cloud/acme cloud/acme
# Since skipping below fails miserably with ansible-core 2.11 and earlier, we have to skip all POSIX tests...
# (https://github.com/ansible/ansible/issues/75711)
# shippable/posix/group1
# Skip all VMs, since we cannot talk to the ACME simulator from these:
# (TODO: remove when ansible-core 2.12 is the earliest version we support)
# skip/aix
# skip/freebsd
# skip/macos
# skip/osx
# skip/rhel

View File

@@ -1,2 +1,3 @@
dependencies: dependencies:
- setup_acme - setup_acme
- setup_remote_tmp_dir

View File

@@ -2,7 +2,7 @@
- block: - block:
- name: Generate account keys - name: Generate account keys
openssl_privatekey: openssl_privatekey:
path: "{{ output_dir }}/{{ item }}.pem" path: "{{ remote_tmp_dir }}/{{ item }}.pem"
type: ECC type: ECC
curve: secp256r1 curve: secp256r1
force: true force: true
@@ -10,7 +10,7 @@
- name: Parse account keys (to ease debugging some test failures) - name: Parse account keys (to ease debugging some test failures)
openssl_privatekey_info: openssl_privatekey_info:
path: "{{ output_dir }}/{{ item }}.pem" path: "{{ remote_tmp_dir }}/{{ item }}.pem"
return_private_key_data: true return_private_key_data: true
loop: "{{ account_keys }}" loop: "{{ account_keys }}"
@@ -22,7 +22,7 @@
- name: Check that account does not exist - name: Check that account does not exist
acme_account_info: acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -31,7 +31,7 @@
- name: Create it now - name: Create it now
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -44,16 +44,21 @@
- name: Check that account exists - name: Check that account exists
acme_account_info: acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
register: account_created register: account_created
- name: Read account key
slurp:
src: '{{ remote_tmp_dir }}/accountkey.pem'
register: slurp
- name: Clear email address - name: Clear email address
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_content: "{{ lookup('file', output_dir ~ '/accountkey.pem') }}" account_key_content: "{{ slurp.content | b64decode }}"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -64,7 +69,7 @@
- name: Check that account was modified - name: Check that account was modified
acme_account_info: acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -74,7 +79,7 @@
- name: Check with wrong account URI - name: Check with wrong account URI
acme_account_info: acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -84,7 +89,7 @@
- name: Check with wrong account key - name: Check with wrong account key
acme_account_info: acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey2.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no

View File

@@ -17,12 +17,12 @@
- name: Remove output directory - name: Remove output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: absent state: absent
- name: Re-create output directory - name: Re-create output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: directory state: directory
- block: - block:

View File

@@ -1,2 +1,14 @@
shippable/cloud/group1 shippable/cloud/group1
cloud/acme cloud/acme
# Since skipping below fails miserably with ansible-core 2.11 and earlier, we have to skip all POSIX tests...
# (https://github.com/ansible/ansible/issues/75711)
# shippable/posix/group1
# Skip all VMs, since we cannot talk to the ACME simulator from these:
# (TODO: remove when ansible-core 2.12 is the earliest version we support)
# skip/aix
# skip/freebsd
# skip/macos
# skip/osx
# skip/rhel

View File

@@ -1,2 +1,5 @@
dependencies: dependencies:
- setup_acme - setup_acme
- setup_pyopenssl # needed for Ubuntu 16.04
- setup_remote_tmp_dir
- prepare_jinja2_compat

View File

@@ -3,7 +3,7 @@
- block: - block:
- name: Generate account keys - name: Generate account keys
openssl_privatekey: openssl_privatekey:
path: "{{ output_dir }}/{{ item.name }}.pem" path: "{{ remote_tmp_dir }}/{{ item.name }}.pem"
type: "{{ item.type }}" type: "{{ item.type }}"
size: "{{ item.size | default(omit) }}" size: "{{ item.size | default(omit) }}"
curve: "{{ item.curve | default(omit) }}" curve: "{{ item.curve | default(omit) }}"
@@ -28,15 +28,19 @@
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/account-ec256.pem" account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
state: absent state: absent
- name: Read account key (EC384)
slurp:
src: '{{ remote_tmp_dir }}/account-ec384.pem'
register: slurp
- name: Create ECC384 account - name: Create ECC384 account
acme_account: acme_account:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
account_key_content: "{{ lookup('file', output_dir ~ '/account-ec384.pem') }}" account_key_content: "{{ slurp.content | b64decode }}"
state: present state: present
allow_creation: yes allow_creation: yes
terms_agreed: yes terms_agreed: yes
@@ -49,7 +53,7 @@
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/account-rsa.pem" account_key_src: "{{ remote_tmp_dir }}/account-rsa.pem"
state: present state: present
allow_creation: yes allow_creation: yes
terms_agreed: yes terms_agreed: yes
@@ -115,6 +119,10 @@
set_fact: set_fact:
cert_2_obtain_results: "{{ certificate_obtain_result }}" cert_2_obtain_results: "{{ certificate_obtain_result }}"
cert_2_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}" cert_2_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}"
- name: Read account key (RSA)
slurp:
src: '{{ remote_tmp_dir }}/account-rsa.pem'
register: slurp_account_key
- name: Obtain cert 3 - name: Obtain cert 3
include_tasks: obtain-cert.yml include_tasks: obtain-cert.yml
vars: vars:
@@ -123,7 +131,7 @@
key_type: ec384 key_type: ec384
subject_alt_name: "DNS:*.example.com,DNS:example.org,DNS:t1.example.com" subject_alt_name: "DNS:*.example.com,DNS:example.org,DNS:t1.example.com"
subject_alt_name_critical: no subject_alt_name_critical: no
account_key_content: "{{ lookup('file', output_dir ~ '/account-rsa.pem') }}" account_key_content: "{{ slurp_account_key.content | b64decode }}"
challenge: dns-01 challenge: dns-01
modify_account: no modify_account: no
deactivate_authzs: no deactivate_authzs: no
@@ -231,6 +239,10 @@
set_fact: set_fact:
cert_5_recreate_2: "{{ challenge_data is changed }}" cert_5_recreate_2: "{{ challenge_data is changed }}"
cert_5c_obtain_results: "{{ certificate_obtain_result }}" cert_5c_obtain_results: "{{ certificate_obtain_result }}"
- name: Read account key (EC384)
slurp:
src: '{{ remote_tmp_dir }}/account-ec384.pem'
register: slurp_account_key
- name: Obtain cert 5 (should again by force) - name: Obtain cert 5 (should again by force)
include_tasks: obtain-cert.yml include_tasks: obtain-cert.yml
vars: vars:
@@ -239,7 +251,7 @@
key_type: ec521 key_type: ec521
subject_alt_name: "DNS:t2.example.com" subject_alt_name: "DNS:t2.example.com"
subject_alt_name_critical: no subject_alt_name_critical: no
account_key_content: "{{ lookup('file', output_dir ~ '/account-ec384.pem') }}" account_key_content: "{{ slurp_account_key.content | b64decode }}"
challenge: http-01 challenge: http-01
modify_account: no modify_account: no
deactivate_authzs: yes deactivate_authzs: yes
@@ -252,189 +264,204 @@
set_fact: set_fact:
cert_5_recreate_3: "{{ challenge_data is changed }}" cert_5_recreate_3: "{{ challenge_data is changed }}"
cert_5d_obtain_results: "{{ certificate_obtain_result }}" cert_5d_obtain_results: "{{ certificate_obtain_result }}"
- name: Obtain cert 6 - block:
include_tasks: obtain-cert.yml - name: Obtain cert 6
vars: include_tasks: obtain-cert.yml
certgen_title: Certificate 6 vars:
certificate_name: cert-6 certgen_title: Certificate 6
key_type: rsa certificate_name: cert-6
rsa_bits: "{{ default_rsa_key_size }}" key_type: rsa
subject_alt_name: "DNS:example.org" rsa_bits: "{{ default_rsa_key_size }}"
subject_alt_name_critical: no subject_alt_name: "DNS:example.org"
account_key: account-ec256 subject_alt_name_critical: no
challenge: tls-alpn-01 account_key: account-ec256
modify_account: yes challenge: tls-alpn-01
deactivate_authzs: no modify_account: yes
force: no deactivate_authzs: no
remaining_days: 10 force: no
terms_agreed: yes remaining_days: 10
account_email: "example@example.org" terms_agreed: yes
acme_expected_root_number: 0 account_email: "example@example.org"
select_chain: acme_expected_root_number: 0
# All intermediates have the same subject key identifier, so always select_chain:
# the first chain will be found, and we need a second condition to # All intermediates have the same subject key identifier, so always
# make sure that the first condition actually works. (The second # the first chain will be found, and we need a second condition to
# condition has been tested above.) # make sure that the first condition actually works. (The second
- test_certificates: first # condition has been tested above.)
subject_key_identifier: "{{ acme_intermediates[0].subject_key_identifier }}" - test_certificates: first
- test_certificates: last subject_key_identifier: "{{ acme_intermediates[0].subject_key_identifier }}"
issuer: "{{ acme_roots[1].subject }}" - test_certificates: last
use_csr_content: true issuer: "{{ acme_roots[1].subject }}"
- name: Store obtain results for cert 6 use_csr_content: true
set_fact: - name: Store obtain results for cert 6
cert_6_obtain_results: "{{ certificate_obtain_result }}" set_fact:
cert_6_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}" cert_6_obtain_results: "{{ certificate_obtain_result }}"
- name: Obtain cert 7 cert_6_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}"
include_tasks: obtain-cert.yml when: acme_intermediates[0].subject_key_identifier is defined
vars: - block:
certgen_title: Certificate 7 - name: Obtain cert 7
certificate_name: cert-7 include_tasks: obtain-cert.yml
key_type: rsa vars:
rsa_bits: "{{ default_rsa_key_size }}" certgen_title: Certificate 7
subject_alt_name: certificate_name: cert-7
- "IP:127.0.0.1" key_type: rsa
# - "IP:::1" rsa_bits: "{{ default_rsa_key_size }}"
subject_alt_name_critical: no subject_alt_name:
account_key: account-ec256 - "IP:127.0.0.1"
challenge: http-01 # - "IP:::1"
modify_account: yes subject_alt_name_critical: no
deactivate_authzs: no account_key: account-ec256
force: no challenge: http-01
remaining_days: 10 modify_account: yes
terms_agreed: yes deactivate_authzs: no
account_email: "example@example.org" force: no
acme_expected_root_number: 2 remaining_days: 10
select_chain: terms_agreed: yes
- test_certificates: last account_email: "example@example.org"
authority_key_identifier: "{{ acme_roots[2].subject_key_identifier }}" acme_expected_root_number: 2
use_csr_content: false select_chain:
- name: Store obtain results for cert 7 - test_certificates: last
set_fact: authority_key_identifier: "{{ acme_roots[2].subject_key_identifier }}"
cert_7_obtain_results: "{{ certificate_obtain_result }}" use_csr_content: false
cert_7_alternate: "{{ 2 if select_crypto_backend == 'cryptography' else 0 }}" - name: Store obtain results for cert 7
- name: Obtain cert 8 set_fact:
include_tasks: obtain-cert.yml cert_7_obtain_results: "{{ certificate_obtain_result }}"
vars: cert_7_alternate: "{{ 2 if select_crypto_backend == 'cryptography' else 0 }}"
certgen_title: Certificate 8 when: acme_roots[2].subject_key_identifier is defined
certificate_name: cert-8 - block:
key_type: rsa - name: Obtain cert 8
rsa_bits: "{{ default_rsa_key_size }}" include_tasks: obtain-cert.yml
subject_alt_name: vars:
- "IP:127.0.0.1" certgen_title: Certificate 8
# IPv4 only since our test validation server doesn't work certificate_name: cert-8
# with IPv6 (thanks to Python's socketserver). key_type: rsa
subject_alt_name_critical: no rsa_bits: "{{ default_rsa_key_size }}"
account_key: account-ec256 subject_alt_name:
challenge: tls-alpn-01 - "IP:127.0.0.1"
challenge_alpn_tls: acme_challenge_cert_helper # IPv4 only since our test validation server doesn't work
modify_account: yes # with IPv6 (thanks to Python's socketserver).
deactivate_authzs: no subject_alt_name_critical: no
force: no account_key: account-ec256
remaining_days: 10 challenge: tls-alpn-01
terms_agreed: yes challenge_alpn_tls: acme_challenge_cert_helper
account_email: "example@example.org" modify_account: yes
use_csr_content: true deactivate_authzs: no
- name: Store obtain results for cert 8 force: no
set_fact: remaining_days: 10
cert_8_obtain_results: "{{ certificate_obtain_result }}" terms_agreed: yes
cert_8_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}" account_email: "example@example.org"
use_csr_content: true
- name: Store obtain results for cert 8
set_fact:
cert_8_obtain_results: "{{ certificate_obtain_result }}"
cert_8_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}"
when: cryptography_version.stdout is version('1.3', '>=')
## DISSECT CERTIFICATES ####################################################################### ## DISSECT CERTIFICATES #######################################################################
# Make sure certificates are valid. Root certificate for Pebble equals the chain certificate. # Make sure certificates are valid. Root certificate for Pebble equals the chain certificate.
- name: Verifying cert 1 - name: Verifying cert 1
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-1-root.pem" -untrusted "{{ output_dir }}/cert-1-chain.pem" "{{ output_dir }}/cert-1.pem"' command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-1-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-1-chain.pem" "{{ remote_tmp_dir }}/cert-1.pem"'
ignore_errors: yes ignore_errors: yes
register: cert_1_valid register: cert_1_valid
- name: Verifying cert 2 - name: Verifying cert 2
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-2-root.pem" -untrusted "{{ output_dir }}/cert-2-chain.pem" "{{ output_dir }}/cert-2.pem"' command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-2-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-2-chain.pem" "{{ remote_tmp_dir }}/cert-2.pem"'
ignore_errors: yes ignore_errors: yes
register: cert_2_valid register: cert_2_valid
- name: Verifying cert 3 - name: Verifying cert 3
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-3-root.pem" -untrusted "{{ output_dir }}/cert-3-chain.pem" "{{ output_dir }}/cert-3.pem"' command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-3-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-3-chain.pem" "{{ remote_tmp_dir }}/cert-3.pem"'
ignore_errors: yes ignore_errors: yes
register: cert_3_valid register: cert_3_valid
- name: Verifying cert 4 - name: Verifying cert 4
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-4-root.pem" -untrusted "{{ output_dir }}/cert-4-chain.pem" "{{ output_dir }}/cert-4.pem"' command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-4-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-4-chain.pem" "{{ remote_tmp_dir }}/cert-4.pem"'
ignore_errors: yes ignore_errors: yes
register: cert_4_valid register: cert_4_valid
- name: Verifying cert 5 - name: Verifying cert 5
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-5-root.pem" -untrusted "{{ output_dir }}/cert-5-chain.pem" "{{ output_dir }}/cert-5.pem"' command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-5-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-5-chain.pem" "{{ remote_tmp_dir }}/cert-5.pem"'
ignore_errors: yes ignore_errors: yes
register: cert_5_valid register: cert_5_valid
- name: Verifying cert 6 - name: Verifying cert 6
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-6-root.pem" -untrusted "{{ output_dir }}/cert-6-chain.pem" "{{ output_dir }}/cert-6.pem"' command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-6-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-6-chain.pem" "{{ remote_tmp_dir }}/cert-6.pem"'
ignore_errors: yes ignore_errors: yes
register: cert_6_valid register: cert_6_valid
when: acme_intermediates[0].subject_key_identifier is defined
- name: Verifying cert 7 - name: Verifying cert 7
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-7-root.pem" -untrusted "{{ output_dir }}/cert-7-chain.pem" "{{ output_dir }}/cert-7.pem"' command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-7-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-7-chain.pem" "{{ remote_tmp_dir }}/cert-7.pem"'
ignore_errors: yes ignore_errors: yes
register: cert_7_valid register: cert_7_valid
when: acme_roots[2].subject_key_identifier is defined
- name: Verifying cert 8 - name: Verifying cert 8
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-8-root.pem" -untrusted "{{ output_dir }}/cert-8-chain.pem" "{{ output_dir }}/cert-8.pem"' command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-8-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-8-chain.pem" "{{ remote_tmp_dir }}/cert-8.pem"'
ignore_errors: yes ignore_errors: yes
register: cert_8_valid register: cert_8_valid
when: cryptography_version.stdout is version('1.3', '>=')
# Dump certificate info # Dump certificate info
- name: Dumping cert 1 - name: Dumping cert 1
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-1.pem" -noout -text' command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-1.pem" -noout -text'
register: cert_1_text register: cert_1_text
- name: Dumping cert 2 - name: Dumping cert 2
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-2.pem" -noout -text' command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-2.pem" -noout -text'
register: cert_2_text register: cert_2_text
- name: Dumping cert 3 - name: Dumping cert 3
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-3.pem" -noout -text' command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-3.pem" -noout -text'
register: cert_3_text register: cert_3_text
- name: Dumping cert 4 - name: Dumping cert 4
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-4.pem" -noout -text' command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-4.pem" -noout -text'
register: cert_4_text register: cert_4_text
- name: Dumping cert 5 - name: Dumping cert 5
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-5.pem" -noout -text' command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-5.pem" -noout -text'
register: cert_5_text register: cert_5_text
- name: Dumping cert 6 - name: Dumping cert 6
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-6.pem" -noout -text' command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-6.pem" -noout -text'
register: cert_6_text register: cert_6_text
when: acme_intermediates[0].subject_key_identifier is defined
- name: Dumping cert 7 - name: Dumping cert 7
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-7.pem" -noout -text' command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-7.pem" -noout -text'
register: cert_7_text register: cert_7_text
when: acme_roots[2].subject_key_identifier is defined
- name: Dumping cert 8 - name: Dumping cert 8
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-8.pem" -noout -text' command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-8.pem" -noout -text'
register: cert_8_text register: cert_8_text
when: cryptography_version.stdout is version('1.3', '>=')
# Dump certificate info # Dump certificate info
- name: Dumping cert 1 - name: Dumping cert 1
x509_certificate_info: x509_certificate_info:
path: "{{ output_dir }}/cert-1.pem" path: "{{ remote_tmp_dir }}/cert-1.pem"
register: cert_1_info register: cert_1_info
- name: Dumping cert 2 - name: Dumping cert 2
x509_certificate_info: x509_certificate_info:
path: "{{ output_dir }}/cert-2.pem" path: "{{ remote_tmp_dir }}/cert-2.pem"
register: cert_2_info register: cert_2_info
- name: Dumping cert 3 - name: Dumping cert 3
x509_certificate_info: x509_certificate_info:
path: "{{ output_dir }}/cert-3.pem" path: "{{ remote_tmp_dir }}/cert-3.pem"
register: cert_3_info register: cert_3_info
- name: Dumping cert 4 - name: Dumping cert 4
x509_certificate_info: x509_certificate_info:
path: "{{ output_dir }}/cert-4.pem" path: "{{ remote_tmp_dir }}/cert-4.pem"
register: cert_4_info register: cert_4_info
- name: Dumping cert 5 - name: Dumping cert 5
x509_certificate_info: x509_certificate_info:
path: "{{ output_dir }}/cert-5.pem" path: "{{ remote_tmp_dir }}/cert-5.pem"
register: cert_5_info register: cert_5_info
- name: Dumping cert 6 - name: Dumping cert 6
x509_certificate_info: x509_certificate_info:
path: "{{ output_dir }}/cert-6.pem" path: "{{ remote_tmp_dir }}/cert-6.pem"
register: cert_6_info register: cert_6_info
when: acme_intermediates[0].subject_key_identifier is defined
- name: Dumping cert 7 - name: Dumping cert 7
x509_certificate_info: x509_certificate_info:
path: "{{ output_dir }}/cert-7.pem" path: "{{ remote_tmp_dir }}/cert-7.pem"
register: cert_7_info register: cert_7_info
when: acme_roots[2].subject_key_identifier is defined
- name: Dumping cert 8 - name: Dumping cert 8
x509_certificate_info: x509_certificate_info:
path: "{{ output_dir }}/cert-8.pem" path: "{{ remote_tmp_dir }}/cert-8.pem"
register: cert_8_info register: cert_8_info
when: cryptography_version.stdout is version('1.3', '>=')
## GET ACCOUNT ORDERS ######################################################################### ## GET ACCOUNT ORDERS #########################################################################
- name: Don't retrieve orders - name: Don't retrieve orders
acme_account_info: acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec256.pem" account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -443,7 +470,7 @@
- name: Retrieve orders as URL list (1/2) - name: Retrieve orders as URL list (1/2)
acme_account_info: acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec256.pem" account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -452,7 +479,7 @@
- name: Retrieve orders as URL list (2/2) - name: Retrieve orders as URL list (2/2)
acme_account_info: acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec384.pem" account_key_src: "{{ remote_tmp_dir }}/account-ec384.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -461,7 +488,7 @@
- name: Retrieve orders as object list (1/2) - name: Retrieve orders as object list (1/2)
acme_account_info: acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec256.pem" account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -470,7 +497,7 @@
- name: Retrieve orders as object list (2/2) - name: Retrieve orders as object list (2/2)
acme_account_info: acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec384.pem" account_key_src: "{{ remote_tmp_dir }}/account-ec384.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no

View File

@@ -8,38 +8,48 @@
- name: Obtain root and intermediate certificates - name: Obtain root and intermediate certificates
get_url: get_url:
url: "http://{{ acme_host }}:5000/{{ item.0 }}-certificate-for-ca/{{ item.1 }}" url: "http://{{ acme_host }}:5000/{{ item.0 }}-certificate-for-ca/{{ item.1 }}"
dest: "{{ output_dir }}/acme-{{ item.0 }}-{{ item.1 }}.pem" dest: "{{ remote_tmp_dir }}/acme-{{ item.0 }}-{{ item.1 }}.pem"
loop: "{{ query('nested', types, root_numbers) }}" loop: "{{ query('nested', types, root_numbers) }}"
- name: Analyze root certificates - name: Analyze root certificates
x509_certificate_info: x509_certificate_info:
path: "{{ output_dir }}/acme-root-{{ item }}.pem" path: "{{ remote_tmp_dir }}/acme-root-{{ item }}.pem"
loop: "{{ root_numbers }}" loop: "{{ root_numbers }}"
register: acme_roots register: acme_roots
- name: Analyze intermediate certificates - name: Analyze intermediate certificates
x509_certificate_info: x509_certificate_info:
path: "{{ output_dir }}/acme-intermediate-{{ item }}.pem" path: "{{ remote_tmp_dir }}/acme-intermediate-{{ item }}.pem"
loop: "{{ root_numbers }}" loop: "{{ root_numbers }}"
register: acme_intermediates register: acme_intermediates
- set_fact: - name: Read root certificates
x__: "{{ item | dict2items | selectattr('key', 'in', interesting_keys) | list | items2dict }}" slurp:
y__: "{{ lookup('file', output_dir ~ '/acme-root-' ~ item.item ~ '.pem', rstrip=False) }}" src: "{{ remote_tmp_dir ~ '/acme-root-' ~ item ~ '.pem' }}"
loop: "{{ acme_roots.results }}" loop: "{{ root_numbers }}"
register: acme_roots_tmp register: slurp_roots
- set_fact:
x__: "{{ item | dict2items | selectattr('key', 'in', interesting_keys) | list | items2dict }}"
loop: "{{ acme_roots.results }}"
register: acme_roots_tmp
- name: Read intermediate certificates
slurp:
src: "{{ remote_tmp_dir ~ '/acme-intermediate-' ~ item ~ '.pem' }}"
loop: "{{ root_numbers }}"
register: slurp_intermediates
- set_fact: - set_fact:
x__: "{{ item | dict2items | selectattr('key', 'in', interesting_keys) | list | items2dict }}" x__: "{{ item | dict2items | selectattr('key', 'in', interesting_keys) | list | items2dict }}"
y__: "{{ lookup('file', output_dir ~ '/acme-intermediate-' ~ item.item ~ '.pem', rstrip=False) }}"
loop: "{{ acme_intermediates.results }}" loop: "{{ acme_intermediates.results }}"
register: acme_intermediates_tmp register: acme_intermediates_tmp
- set_fact: - set_fact:
acme_roots: "{{ acme_roots_tmp.results | map(attribute='ansible_facts.x__') | list }}" acme_roots: "{{ acme_roots_tmp.results | map(attribute='ansible_facts.x__') | list }}"
acme_root_certs: "{{ acme_roots_tmp.results | map(attribute='ansible_facts.y__') | list }}" acme_root_certs: "{{ slurp_roots.results | map(attribute='content') | map('b64decode') | list }}"
acme_intermediates: "{{ acme_intermediates_tmp.results | map(attribute='ansible_facts.x__') | list }}" acme_intermediates: "{{ acme_intermediates_tmp.results | map(attribute='ansible_facts.x__') | list }}"
acme_intermediate_certs: "{{ acme_intermediates_tmp.results | map(attribute='ansible_facts.y__') | list }}" acme_intermediate_certs: "{{ slurp_intermediates.results | map(attribute='content') | map('b64decode') | list }}"
vars: vars:
types: types:
@@ -88,12 +98,12 @@
- name: Remove output directory - name: Remove output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: absent state: absent
- name: Re-create output directory - name: Re-create output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: directory state: directory
- block: - block:

View File

@@ -7,6 +7,14 @@
assert: assert:
that: that:
- "'DNS:example.com' in cert_1_text.stdout" - "'DNS:example.com' in cert_1_text.stdout"
- name: Read certificate 1 files
slurp:
src: '{{ remote_tmp_dir }}/{{ item }}'
loop:
- cert-1.pem
- cert-1-chain.pem
- cert-1-fullchain.pem
register: slurp
- name: Check that certificate 1 retrieval got all chains - name: Check that certificate 1 retrieval got all chains
assert: assert:
that: that:
@@ -15,9 +23,9 @@
- "'cert' in cert_1_obtain_results.all_chains[cert_1_alternate | int]" - "'cert' in cert_1_obtain_results.all_chains[cert_1_alternate | int]"
- "'chain' in cert_1_obtain_results.all_chains[cert_1_alternate | int]" - "'chain' in cert_1_obtain_results.all_chains[cert_1_alternate | int]"
- "'full_chain' in cert_1_obtain_results.all_chains[cert_1_alternate | int]" - "'full_chain' in cert_1_obtain_results.all_chains[cert_1_alternate | int]"
- "lookup('file', output_dir ~ '/cert-1.pem', rstrip=False) == cert_1_obtain_results.all_chains[cert_1_alternate | int].cert" - "(slurp.results[0].content | b64decode) == cert_1_obtain_results.all_chains[cert_1_alternate | int].cert"
- "lookup('file', output_dir ~ '/cert-1-chain.pem', rstrip=False) == cert_1_obtain_results.all_chains[cert_1_alternate | int].chain" - "(slurp.results[1].content | b64decode) == cert_1_obtain_results.all_chains[cert_1_alternate | int].chain"
- "lookup('file', output_dir ~ '/cert-1-fullchain.pem', rstrip=False) == cert_1_obtain_results.all_chains[cert_1_alternate | int].full_chain" - "(slurp.results[2].content | b64decode) == cert_1_obtain_results.all_chains[cert_1_alternate | int].full_chain"
- name: Check that certificate 2 is valid - name: Check that certificate 2 is valid
assert: assert:
@@ -28,6 +36,14 @@
that: that:
- "'DNS:*.example.com' in cert_2_text.stdout" - "'DNS:*.example.com' in cert_2_text.stdout"
- "'DNS:example.com' in cert_2_text.stdout" - "'DNS:example.com' in cert_2_text.stdout"
- name: Read certificate 2 files
slurp:
src: '{{ remote_tmp_dir }}/{{ item }}'
loop:
- cert-2.pem
- cert-2-chain.pem
- cert-2-fullchain.pem
register: slurp
- name: Check that certificate 1 retrieval got all chains - name: Check that certificate 1 retrieval got all chains
assert: assert:
that: that:
@@ -36,9 +52,9 @@
- "'cert' in cert_2_obtain_results.all_chains[cert_2_alternate | int]" - "'cert' in cert_2_obtain_results.all_chains[cert_2_alternate | int]"
- "'chain' in cert_2_obtain_results.all_chains[cert_2_alternate | int]" - "'chain' in cert_2_obtain_results.all_chains[cert_2_alternate | int]"
- "'full_chain' in cert_2_obtain_results.all_chains[cert_2_alternate | int]" - "'full_chain' in cert_2_obtain_results.all_chains[cert_2_alternate | int]"
- "lookup('file', output_dir ~ '/cert-2.pem', rstrip=False) == cert_2_obtain_results.all_chains[cert_2_alternate | int].cert" - "(slurp.results[0].content | b64decode) == cert_2_obtain_results.all_chains[cert_2_alternate | int].cert"
- "lookup('file', output_dir ~ '/cert-2-chain.pem', rstrip=False) == cert_2_obtain_results.all_chains[cert_2_alternate | int].chain" - "(slurp.results[1].content | b64decode) == cert_2_obtain_results.all_chains[cert_2_alternate | int].chain"
- "lookup('file', output_dir ~ '/cert-2-fullchain.pem', rstrip=False) == cert_2_obtain_results.all_chains[cert_2_alternate | int].full_chain" - "(slurp.results[2].content | b64decode) == cert_2_obtain_results.all_chains[cert_2_alternate | int].full_chain"
- name: Check that certificate 3 is valid - name: Check that certificate 3 is valid
assert: assert:
@@ -50,6 +66,14 @@
- "'DNS:*.example.com' in cert_3_text.stdout" - "'DNS:*.example.com' in cert_3_text.stdout"
- "'DNS:example.org' in cert_3_text.stdout" - "'DNS:example.org' in cert_3_text.stdout"
- "'DNS:t1.example.com' in cert_3_text.stdout" - "'DNS:t1.example.com' in cert_3_text.stdout"
- name: Read certificate 3 files
slurp:
src: '{{ remote_tmp_dir }}/{{ item }}'
loop:
- cert-3.pem
- cert-3-chain.pem
- cert-3-fullchain.pem
register: slurp
- name: Check that certificate 1 retrieval got all chains - name: Check that certificate 1 retrieval got all chains
assert: assert:
that: that:
@@ -58,9 +82,9 @@
- "'cert' in cert_3_obtain_results.all_chains[cert_3_alternate | int]" - "'cert' in cert_3_obtain_results.all_chains[cert_3_alternate | int]"
- "'chain' in cert_3_obtain_results.all_chains[cert_3_alternate | int]" - "'chain' in cert_3_obtain_results.all_chains[cert_3_alternate | int]"
- "'full_chain' in cert_3_obtain_results.all_chains[cert_3_alternate | int]" - "'full_chain' in cert_3_obtain_results.all_chains[cert_3_alternate | int]"
- "lookup('file', output_dir ~ '/cert-3.pem', rstrip=False) == cert_3_obtain_results.all_chains[cert_3_alternate | int].cert" - "(slurp.results[0].content | b64decode) == cert_3_obtain_results.all_chains[cert_3_alternate | int].cert"
- "lookup('file', output_dir ~ '/cert-3-chain.pem', rstrip=False) == cert_3_obtain_results.all_chains[cert_3_alternate | int].chain" - "(slurp.results[1].content | b64decode) == cert_3_obtain_results.all_chains[cert_3_alternate | int].chain"
- "lookup('file', output_dir ~ '/cert-3-fullchain.pem', rstrip=False) == cert_3_obtain_results.all_chains[cert_3_alternate | int].full_chain" - "(slurp.results[2].content | b64decode) == cert_3_obtain_results.all_chains[cert_3_alternate | int].full_chain"
- name: Check that certificate 4 is valid - name: Check that certificate 4 is valid
assert: assert:
@@ -100,14 +124,38 @@
that: that:
- cert_5_recreate_3 == True - cert_5_recreate_3 == True
- name: Check that certificate 6 is valid - block:
assert: - name: Check that certificate 6 is valid
that: assert:
- cert_6_valid is not failed that:
- name: Check that certificate 6 contains correct SANs - cert_6_valid is not failed
assert: - name: Check that certificate 6 contains correct SANs
that: assert:
- "'DNS:example.org' in cert_6_text.stdout" that:
- "'DNS:example.org' in cert_6_text.stdout"
when: acme_intermediates[0].subject_key_identifier is defined
- block:
- name: Check that certificate 7 is valid
assert:
that:
- cert_7_valid is not failed
- name: Check that certificate 7 contains correct SANs
assert:
that:
- "'IP Address:127.0.0.1' in cert_8_text.stdout or 'IP:127.0.0.1' in cert_8_text.stdout"
when: acme_roots[2].subject_key_identifier is defined
- block:
- name: Check that certificate 8 is valid
assert:
that:
- cert_8_valid is not failed
- name: Check that certificate 8 contains correct SANs
assert:
that:
- "'IP Address:127.0.0.1' in cert_8_text.stdout or 'IP:127.0.0.1' in cert_8_text.stdout"
when: cryptography_version.stdout is version('1.3', '>=')
- name: Validate that orders were not retrieved - name: Validate that orders were not retrieved
assert: assert:

View File

@@ -1,2 +1,14 @@
shippable/cloud/group1 shippable/cloud/group1
cloud/acme cloud/acme
# Since skipping below fails miserably with ansible-core 2.11 and earlier, we have to skip all POSIX tests...
# (https://github.com/ansible/ansible/issues/75711)
# shippable/posix/group1
# Skip all VMs, since we cannot talk to the ACME simulator from these:
# (TODO: remove when ansible-core 2.12 is the earliest version we support)
# skip/aix
# skip/freebsd
# skip/macos
# skip/osx
# skip/rhel

View File

@@ -1,2 +1,3 @@
dependencies: dependencies:
- setup_acme - setup_acme
- setup_remote_tmp_dir

View File

@@ -3,7 +3,7 @@
- block: - block:
- name: Generate account keys - name: Generate account keys
openssl_privatekey: openssl_privatekey:
path: "{{ output_dir }}/{{ item.name }}.pem" path: "{{ remote_tmp_dir }}/{{ item.name }}.pem"
type: "{{ item.type }}" type: "{{ item.type }}"
size: "{{ item.size | default(omit) }}" size: "{{ item.size | default(omit) }}"
curve: "{{ item.curve | default(omit) }}" curve: "{{ item.curve | default(omit) }}"
@@ -22,6 +22,10 @@
type: RSA type: RSA
size: "{{ default_rsa_key_size }}" size: "{{ default_rsa_key_size }}"
## CREATE ACCOUNTS AND OBTAIN CERTIFICATES #################################################### ## CREATE ACCOUNTS AND OBTAIN CERTIFICATES ####################################################
- name: Read account key (EC256)
slurp:
src: '{{ remote_tmp_dir }}/account-ec256.pem'
register: slurp_account_key
- name: Obtain cert 1 - name: Obtain cert 1
include_tasks: obtain-cert.yml include_tasks: obtain-cert.yml
vars: vars:
@@ -31,7 +35,7 @@
rsa_bits: "{{ default_rsa_key_size }}" rsa_bits: "{{ default_rsa_key_size }}"
subject_alt_name: "DNS:example.com" subject_alt_name: "DNS:example.com"
subject_alt_name_critical: no subject_alt_name_critical: no
account_key_content: "{{ lookup('file', output_dir ~ '/account-ec256.pem') }}" account_key_content: "{{ slurp_account_key.content | b64decode }}"
challenge: http-01 challenge: http-01
modify_account: yes modify_account: yes
deactivate_authzs: no deactivate_authzs: no
@@ -76,8 +80,8 @@
- name: Revoke certificate 1 via account key - name: Revoke certificate 1 via account key
acme_certificate_revoke: acme_certificate_revoke:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec256.pem" account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
certificate: "{{ output_dir }}/cert-1.pem" certificate: "{{ remote_tmp_dir }}/cert-1.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
@@ -86,19 +90,23 @@
- name: Revoke certificate 2 via certificate private key - name: Revoke certificate 2 via certificate private key
acme_certificate_revoke: acme_certificate_revoke:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
private_key_src: "{{ output_dir }}/cert-2.key" private_key_src: "{{ remote_tmp_dir }}/cert-2.key"
private_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}" private_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
certificate: "{{ output_dir }}/cert-2.pem" certificate: "{{ remote_tmp_dir }}/cert-2.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no
ignore_errors: yes ignore_errors: yes
register: cert_2_revoke register: cert_2_revoke
- name: Read account key (RSA)
slurp:
src: '{{ remote_tmp_dir }}/account-rsa.pem'
register: slurp_account_key
- name: Revoke certificate 3 via account key (fullchain) - name: Revoke certificate 3 via account key (fullchain)
acme_certificate_revoke: acme_certificate_revoke:
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
account_key_content: "{{ lookup('file', output_dir ~ '/account-rsa.pem') }}" account_key_content: "{{ slurp_account_key.content | b64decode }}"
certificate: "{{ output_dir }}/cert-3-fullchain.pem" certificate: "{{ remote_tmp_dir }}/cert-3-fullchain.pem"
acme_version: 2 acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no validate_certs: no

View File

@@ -17,12 +17,12 @@
- name: Remove output directory - name: Remove output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: absent state: absent
- name: Re-create output directory - name: Re-create output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: directory state: directory
- block: - block:

View File

@@ -1,2 +1,14 @@
shippable/cloud/group1 shippable/cloud/group1
cloud/acme cloud/acme
# Since skipping below fails miserably with ansible-core 2.11 and earlier, we have to skip all POSIX tests...
# (https://github.com/ansible/ansible/issues/75711)
# shippable/posix/group1
# Skip all VMs, since we cannot talk to the ACME simulator from these:
# (TODO: remove when ansible-core 2.12 is the earliest version we support)
# skip/aix
# skip/freebsd
# skip/macos
# skip/osx
# skip/rhel

View File

@@ -1,2 +1,3 @@
dependencies: dependencies:
- setup_acme - setup_acme
- setup_remote_tmp_dir

View File

@@ -7,7 +7,7 @@
- block: - block:
- name: Generate ECC256 accoun keys - name: Generate ECC256 accoun keys
openssl_privatekey: openssl_privatekey:
path: "{{ output_dir }}/account-ec256.pem" path: "{{ remote_tmp_dir }}/account-ec256.pem"
type: ECC type: ECC
curve: secp256r1 curve: secp256r1
force: true force: true
@@ -31,4 +31,4 @@
terms_agreed: yes terms_agreed: yes
account_email: "example@example.org" account_email: "example@example.org"
when: openssl_version.stdout is version('1.0.0', '>=') or cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('1.5', '>=')

View File

@@ -1,2 +1,14 @@
shippable/cloud/group1 shippable/cloud/group1
cloud/acme cloud/acme
# Since skipping below fails miserably with ansible-core 2.11 and earlier, we have to skip all POSIX tests...
# (https://github.com/ansible/ansible/issues/75711)
# shippable/posix/group1
# Skip all VMs, since we cannot talk to the ACME simulator from these:
# (TODO: remove when ansible-core 2.12 is the earliest version we support)
# skip/aix
# skip/freebsd
# skip/macos
# skip/osx
# skip/rhel

View File

@@ -1,2 +1,4 @@
dependencies: dependencies:
- setup_acme - setup_acme
- setup_remote_tmp_dir
- prepare_jinja2_compat

View File

@@ -2,7 +2,7 @@
- block: - block:
- name: Generate account keys - name: Generate account keys
openssl_privatekey: openssl_privatekey:
path: "{{ output_dir }}/{{ item }}.pem" path: "{{ remote_tmp_dir }}/{{ item }}.pem"
type: ECC type: ECC
curve: secp256r1 curve: secp256r1
force: true force: true
@@ -10,7 +10,7 @@
- name: Parse account keys (to ease debugging some test failures) - name: Parse account keys (to ease debugging some test failures)
openssl_privatekey_info: openssl_privatekey_info:
path: "{{ output_dir }}/{{ item }}.pem" path: "{{ remote_tmp_dir }}/{{ item }}.pem"
return_private_key_data: true return_private_key_data: true
loop: "{{ account_keys }}" loop: "{{ account_keys }}"
@@ -32,7 +32,7 @@
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2 acme_version: 2
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
url: "{{ directory.directory.newAccount}}" url: "{{ directory.directory.newAccount}}"
method: post method: post
content: '{"termsOfServiceAgreed":true}' content: '{"termsOfServiceAgreed":true}'
@@ -46,7 +46,7 @@
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2 acme_version: 2
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}" account_uri: "{{ account_creation.headers.location }}"
url: "{{ account_creation.headers.location }}" url: "{{ account_creation.headers.location }}"
method: get method: get
@@ -58,7 +58,7 @@
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2 acme_version: 2
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}" account_uri: "{{ account_creation.headers.location }}"
url: "{{ account_creation.headers.location }}" url: "{{ account_creation.headers.location }}"
method: post method: post
@@ -77,7 +77,7 @@
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2 acme_version: 2
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}" account_uri: "{{ account_creation.headers.location }}"
url: "{{ directory.directory.newOrder }}" url: "{{ directory.directory.newOrder }}"
method: post method: post
@@ -100,7 +100,7 @@
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2 acme_version: 2
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}" account_uri: "{{ account_creation.headers.location }}"
url: "{{ new_order.headers.location }}" url: "{{ new_order.headers.location }}"
method: get method: get
@@ -112,7 +112,7 @@
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2 acme_version: 2
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}" account_uri: "{{ account_creation.headers.location }}"
url: "{{ item }}" url: "{{ item }}"
method: get method: get
@@ -125,7 +125,7 @@
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2 acme_version: 2
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}" account_uri: "{{ account_creation.headers.location }}"
url: "{{ (item.challenges | selectattr('type', 'equalto', 'http-01') | list)[0].url }}" url: "{{ (item.challenges | selectattr('type', 'equalto', 'http-01') | list)[0].url }}"
method: get method: get
@@ -138,7 +138,7 @@
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2 acme_version: 2
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}" account_uri: "{{ account_creation.headers.location }}"
url: "{{ item.url }}" url: "{{ item.url }}"
method: post method: post
@@ -152,7 +152,7 @@
acme_directory: https://{{ acme_host }}:14000/dir acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2 acme_version: 2
validate_certs: no validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem" account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}" account_uri: "{{ account_creation.headers.location }}"
url: "{{ item.url }}" url: "{{ item.url }}"
method: get method: get

View File

@@ -17,12 +17,12 @@
- name: Remove output directory - name: Remove output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: absent state: absent
- name: Re-create output directory - name: Re-create output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: directory state: directory
- block: - block:

View File

@@ -1 +1,2 @@
shippable/cloud/group1
shippable/posix/group1 shippable/posix/group1

View File

@@ -1,2 +1,3 @@
dependencies: dependencies:
- setup_openssl
- setup_remote_tmp_dir - setup_remote_tmp_dir

View File

@@ -3,9 +3,6 @@
# and should not be used as examples of how to write Ansible roles # # and should not be used as examples of how to write Ansible roles #
#################################################################### ####################################################################
- name: register cryptography version
command: '{{ ansible_python.executable }} -c ''import cryptography; print(cryptography.__version__)'''
register: cryptography_version
- block: - block:
- name: Make sure testhost directory exists - name: Make sure testhost directory exists
file: file:
@@ -16,10 +13,9 @@
copy: copy:
src: '{{ role_path }}/files/' src: '{{ role_path }}/files/'
dest: '{{ remote_tmp_dir }}/files/' dest: '{{ remote_tmp_dir }}/files/'
remote_src: yes
- name: Find root for cert 1 - name: Find root for cert 1
certificate_complete_chain: certificate_complete_chain:
input_chain: '{{ lookup(''file'', ''cert1-fullchain.pem'', rstrip=False) }}' input_chain: '{{ lookup("file", "cert1-fullchain.pem", rstrip=False) }}'
root_certificates: root_certificates:
- '{{ remote_tmp_dir }}/files/roots/' - '{{ remote_tmp_dir }}/files/roots/'
register: cert1_root register: cert1_root
@@ -30,7 +26,7 @@
- cert1_root.root == lookup('file', 'cert1-root.pem', rstrip=False) - cert1_root.root == lookup('file', 'cert1-root.pem', rstrip=False)
- name: Find rootchain for cert 1 - name: Find rootchain for cert 1
certificate_complete_chain: certificate_complete_chain:
input_chain: '{{ lookup(''file'', ''cert1.pem'', rstrip=False) }}' input_chain: '{{ lookup("file", "cert1.pem", rstrip=False) }}'
intermediate_certificates: intermediate_certificates:
- '{{ remote_tmp_dir }}/files/cert1-chain.pem' - '{{ remote_tmp_dir }}/files/cert1-chain.pem'
root_certificates: root_certificates:
@@ -44,7 +40,7 @@
- cert1_rootchain.root == lookup('file', 'cert1-root.pem', rstrip=False) - cert1_rootchain.root == lookup('file', 'cert1-root.pem', rstrip=False)
- name: Find root for cert 2 - name: Find root for cert 2
certificate_complete_chain: certificate_complete_chain:
input_chain: '{{ lookup(''file'', ''cert2-fullchain.pem'', rstrip=False) }}' input_chain: '{{ lookup("file", "cert2-fullchain.pem", rstrip=False) }}'
root_certificates: root_certificates:
- '{{ remote_tmp_dir }}/files/roots/' - '{{ remote_tmp_dir }}/files/roots/'
register: cert2_root register: cert2_root
@@ -55,7 +51,7 @@
- cert2_root.root == lookup('file', 'cert2-root.pem', rstrip=False) - cert2_root.root == lookup('file', 'cert2-root.pem', rstrip=False)
- name: Find rootchain for cert 2 - name: Find rootchain for cert 2
certificate_complete_chain: certificate_complete_chain:
input_chain: '{{ lookup(''file'', ''cert2.pem'', rstrip=False) }}' input_chain: '{{ lookup("file", "cert2.pem", rstrip=False) }}'
intermediate_certificates: intermediate_certificates:
- '{{ remote_tmp_dir }}/files/cert2-chain.pem' - '{{ remote_tmp_dir }}/files/cert2-chain.pem'
root_certificates: root_certificates:
@@ -69,7 +65,7 @@
- cert2_rootchain.root == lookup('file', 'cert2-root.pem', rstrip=False) - cert2_rootchain.root == lookup('file', 'cert2-root.pem', rstrip=False)
- name: Find alternate rootchain for cert 2 - name: Find alternate rootchain for cert 2
certificate_complete_chain: certificate_complete_chain:
input_chain: '{{ lookup(''file'', ''cert2.pem'', rstrip=True) }}' input_chain: '{{ lookup("file", "cert2.pem", rstrip=True) }}'
intermediate_certificates: intermediate_certificates:
- '{{ remote_tmp_dir }}/files/cert2-altchain.pem' - '{{ remote_tmp_dir }}/files/cert2-altchain.pem'
root_certificates: root_certificates:

View File

@@ -1,3 +1,4 @@
shippable/cloud/group1
shippable/posix/group1 shippable/posix/group1
destructive destructive
needs/httptester needs/httptester

View File

@@ -4,16 +4,35 @@
# and should not be used as examples of how to write Ansible roles # # and should not be used as examples of how to write Ansible roles #
#################################################################### ####################################################################
- set_fact:
skip_tests: false
- block: - block:
- name: Get servers certificate with backend auto-detection - name: Get servers certificate with backend auto-detection
get_certificate: get_certificate:
host: "{{ httpbin_host }}" host: "{{ httpbin_host }}"
port: 443 port: 443
ignore_errors: true
register: result
- set_fact:
skip_tests: |
{{
result is failed and (
'error: [Errno 1] _ssl.c:492: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure' in result.msg
or
'error: _ssl.c:314: Invalid SSL protocol variant specified.' in result.msg
)
}}
- assert:
that:
- result is success or skip_tests
when: | when: |
pyopenssl_version.stdout is version('0.15', '>=') or pyopenssl_version.stdout is version('0.15', '>=') or
(cryptography_version.stdout is version('1.6', '>=') and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)) cryptography_version.stdout is version('1.6', '>=')
- block: - block:
@@ -21,17 +40,7 @@
vars: vars:
select_crypto_backend: pyopenssl select_crypto_backend: pyopenssl
when: pyopenssl_version.stdout is version('0.15', '>=') when: pyopenssl_version.stdout is version('0.15', '>=') and not skip_tests
- name: Remove output directory
file:
path: "{{ output_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
state: directory
- block: - block:
@@ -42,6 +51,4 @@
# The module doesn't work with CentOS 6. Since the pyOpenSSL installed there is too old, # The module doesn't work with CentOS 6. Since the pyOpenSSL installed there is too old,
# we never noticed before. This becomes a problem with the new cryptography backend, # we never noticed before. This becomes a problem with the new cryptography backend,
# since there is a new enough cryptography version... # since there is a new enough cryptography version...
when: | when: cryptography_version.stdout is version('1.6', '>=') and not skip_tests
cryptography_version.stdout is version('1.6', '>=') and
(ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)

View File

@@ -97,14 +97,19 @@
# We got the correct response from the module # We got the correct response from the module
- "'ca_cert file does not exist' == result.msg" - "'ca_cert file does not exist' == result.msg"
- name: Get a temp directory
tempfile:
state: directory
register: my_temp_dir
- name: Download CA Cert as pem from server - name: Download CA Cert as pem from server
get_url: get_url:
url: "http://ansible.http.tests/cacert.pem" url: "http://ansible.http.tests/cacert.pem"
dest: "{{ output_dir }}/temp.pem" dest: "{{ my_temp_dir.path }}/temp.pem"
- name: Get servers certificate comparing it to its own ca_cert file - name: Get servers certificate comparing it to its own ca_cert file
get_certificate: get_certificate:
ca_cert: '{{ output_dir }}/temp.pem' ca_cert: '{{ my_temp_dir.path }}/temp.pem'
host: "{{ httpbin_host }}" host: "{{ httpbin_host }}"
port: 443 port: 443
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
@@ -115,11 +120,6 @@
- result is not changed - result is not changed
- result is not failed - result is not failed
- name: Get a temp directory
tempfile:
state: directory
register: my_temp_dir
- name: Deploy the bogus_ca.pem file - name: Deploy the bogus_ca.pem file
copy: copy:
src: "bogus_ca.pem" src: "bogus_ca.pem"

View File

@@ -0,0 +1,2 @@
dependencies:
- setup_remote_tmp_dir

View File

@@ -4,18 +4,25 @@
# and should not be used as examples of how to write Ansible roles # # and should not be used as examples of how to write Ansible roles #
#################################################################### ####################################################################
- name: Copy keyfiles
copy:
src: '{{ item }}'
dest: '{{ remote_tmp_dir }}/{{ item }}'
loop:
- keyfile1
- keyfile2
- name: Make sure cryptsetup is installed - name: Make sure cryptsetup is installed
package: package:
name: cryptsetup name: cryptsetup
state: present state: present
become: yes become: yes
- name: Create cryptfile - name: Create cryptfile
command: dd if=/dev/zero of={{ output_dir.replace('~', ansible_env.HOME) }}/cryptfile bs=1M count=32 command: dd if=/dev/zero of={{ remote_tmp_dir.replace('~', ansible_env.HOME) }}/cryptfile bs=1M count=32
- name: Create lookback device - name: Create lookback device
command: losetup -f {{ output_dir.replace('~', ansible_env.HOME) }}/cryptfile command: losetup -f {{ remote_tmp_dir.replace('~', ansible_env.HOME) }}/cryptfile
become: yes become: yes
- name: Determine loop device name - name: Determine loop device name
command: losetup -j {{ output_dir.replace('~', ansible_env.HOME) }}/cryptfile --output name command: losetup -j {{ remote_tmp_dir.replace('~', ansible_env.HOME) }}/cryptfile --output name
become: yes become: yes
register: cryptfile_device_output register: cryptfile_device_output
- set_fact: - set_fact:
@@ -37,5 +44,5 @@
- command: losetup -d "{{ cryptfile_device }}" - command: losetup -d "{{ cryptfile_device }}"
become: yes become: yes
- file: - file:
dest: "{{ output_dir }}/cryptfile" dest: "{{ remote_tmp_dir }}/cryptfile"
state: absent state: absent

View File

@@ -3,7 +3,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
check_mode: yes check_mode: yes
@@ -13,7 +13,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
become: yes become: yes
@@ -22,7 +22,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
become: yes become: yes
@@ -31,7 +31,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
check_mode: yes check_mode: yes
@@ -48,7 +48,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
check_mode: yes check_mode: yes
become: yes become: yes
register: open_check register: open_check
@@ -56,21 +56,21 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes become: yes
register: open register: open
- name: Open (idempotent) - name: Open (idempotent)
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes become: yes
register: open_idem register: open_idem
- name: Open (idempotent, check) - name: Open (idempotent, check)
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
check_mode: yes check_mode: yes
become: yes become: yes
register: open_idem_check register: open_idem_check
@@ -118,7 +118,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes become: yes
- name: Closed (via device, check) - name: Closed (via device, check)
@@ -158,7 +158,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes become: yes
- name: Absent (check) - name: Absent (check)

View File

@@ -3,7 +3,7 @@
luks_device: luks_device:
device: /dev/asdfasdfasdf device: /dev/asdfasdfasdf
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
check_mode: yes check_mode: yes
@@ -14,7 +14,7 @@
luks_device: luks_device:
device: /dev/asdfasdfasdf device: /dev/asdfasdfasdf
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
ignore_errors: yes ignore_errors: yes
@@ -31,7 +31,7 @@
luks_device: luks_device:
device: /tmp/ device: /tmp/
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
check_mode: yes check_mode: yes
@@ -42,7 +42,7 @@
luks_device: luks_device:
device: /tmp/ device: /tmp/
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
ignore_errors: yes ignore_errors: yes

View File

@@ -3,7 +3,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: closed state: closed
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
become: yes become: yes
@@ -14,7 +14,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
register: open_try register: open_try
@@ -31,7 +31,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile2" keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
register: open_try register: open_try
@@ -43,8 +43,8 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: closed state: closed
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
new_keyfile: "{{ role_path }}/files/keyfile2" new_keyfile: "{{ remote_tmp_dir }}/keyfile2"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
become: yes become: yes
@@ -54,8 +54,8 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: closed state: closed
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
new_keyfile: "{{ role_path }}/files/keyfile2" new_keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes become: yes
register: result_2 register: result_2
@@ -70,7 +70,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile2" keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
register: open_try register: open_try
@@ -91,8 +91,8 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: closed state: closed
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
remove_keyfile: "{{ role_path }}/files/keyfile1" remove_keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes become: yes
register: result_1 register: result_1
@@ -100,8 +100,8 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: closed state: closed
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
remove_keyfile: "{{ role_path }}/files/keyfile1" remove_keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes become: yes
register: result_2 register: result_2
@@ -116,7 +116,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
register: open_try register: open_try
@@ -128,7 +128,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile2" keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
register: open_try register: open_try
@@ -149,8 +149,8 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: closed state: closed
keyfile: "{{ role_path }}/files/keyfile2" keyfile: "{{ remote_tmp_dir }}/keyfile2"
remove_keyfile: "{{ role_path }}/files/keyfile2" remove_keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
register: remove_last_key register: remove_last_key
@@ -165,7 +165,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile2" keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
register: open_try register: open_try
@@ -182,8 +182,8 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: closed state: closed
keyfile: "{{ role_path }}/files/keyfile2" keyfile: "{{ remote_tmp_dir }}/keyfile2"
remove_keyfile: "{{ role_path }}/files/keyfile2" remove_keyfile: "{{ remote_tmp_dir }}/keyfile2"
force_remove_last_key: yes force_remove_last_key: yes
become: yes become: yes
@@ -193,7 +193,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile2" keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
register: open_try register: open_try

View File

@@ -3,7 +3,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
keysize: 256 keysize: 256
pbkdf: pbkdf:
iteration_count: 1000 iteration_count: 1000
@@ -13,7 +13,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
keysize: 256 keysize: 256
pbkdf: pbkdf:
iteration_count: 1000 iteration_count: 1000
@@ -23,7 +23,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
keysize: 512 keysize: 512
pbkdf: pbkdf:
iteration_count: 1000 iteration_count: 1000
@@ -33,7 +33,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: present state: present
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
passphrase: "{{ cryptfile_passphrase1 }}" passphrase: "{{ cryptfile_passphrase1 }}"
pbkdf: pbkdf:
iteration_count: 1000 iteration_count: 1000

View File

@@ -54,7 +54,7 @@
state: closed state: closed
passphrase: "{{ cryptfile_passphrase1 }}" passphrase: "{{ cryptfile_passphrase1 }}"
new_passphrase: "{{ cryptfile_passphrase2 }}" new_passphrase: "{{ cryptfile_passphrase2 }}"
new_keyfile: "{{ role_path }}/files/keyfile1" new_keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
become: yes become: yes
@@ -122,7 +122,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
register: open_try register: open_try
@@ -135,7 +135,7 @@
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: closed state: closed
passphrase: "{{ cryptfile_passphrase1 }}" passphrase: "{{ cryptfile_passphrase1 }}"
new_keyfile: "{{ role_path }}/files/keyfile1" new_keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1
become: yes become: yes
@@ -144,7 +144,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: closed state: closed
remove_keyfile: "{{ role_path }}/files/keyfile1" remove_keyfile: "{{ remote_tmp_dir }}/keyfile1"
remove_passphrase: "{{ cryptfile_passphrase1 }}" remove_passphrase: "{{ cryptfile_passphrase1 }}"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
@@ -157,7 +157,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: opened state: opened
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
register: open_try register: open_try
@@ -219,7 +219,7 @@
luks_device: luks_device:
device: "{{ cryptfile_device }}" device: "{{ cryptfile_device }}"
state: closed state: closed
keyfile: "{{ role_path }}/files/keyfile1" keyfile: "{{ remote_tmp_dir }}/keyfile1"
new_passphrase: "{{ cryptfile_passphrase3 }}" new_passphrase: "{{ cryptfile_passphrase3 }}"
pbkdf: pbkdf:
iteration_time: 0.1 iteration_time: 0.1

View File

@@ -1,3 +1,4 @@
dependencies: dependencies:
- setup_ssh_keygen - setup_ssh_keygen
- setup_ssh_agent - setup_ssh_agent
- setup_remote_tmp_dir

View File

@@ -5,9 +5,9 @@
- name: Declare global variables - name: Declare global variables
set_fact: set_fact:
signing_key: '{{ output_dir }}/id_key' signing_key: '{{ remote_tmp_dir }}/id_key'
public_key: '{{ output_dir }}/id_key.pub' public_key: '{{ remote_tmp_dir }}/id_key.pub'
certificate_path: '{{ output_dir }}/id_cert' certificate_path: '{{ remote_tmp_dir }}/id_cert'
- name: Generate keypair - name: Generate keypair
openssh_keypair: openssh_keypair:

View File

@@ -4,8 +4,8 @@
#################################################################### ####################################################################
- set_fact: - set_fact:
new_signing_key: "{{ output_dir }}/new_key" new_signing_key: "{{ remote_tmp_dir }}/new_key"
new_public_key: "{{ output_dir }}/new_key.pub" new_public_key: "{{ remote_tmp_dir }}/new_key.pub"
- name: Generate new test key - name: Generate new test key
openssh_keypair: openssh_keypair:
@@ -20,6 +20,81 @@
valid_from: always valid_from: always
valid_to: forever valid_to: forever
- block:
- name: Generate cert with updated signature algorithm
openssh_cert:
type: user
path: "{{ certificate_path }}"
public_key: "{{ public_key }}"
signing_key: "{{ signing_key }}"
signature_algorithm: rsa-sha2-256
valid_from: always
valid_to: forever
register: updated_signature_algorithm
- name: Assert signature algorithm update causes change
assert:
that:
- updated_signature_algorithm is changed
- name: Generate cert with updated signature algorithm (idempotent)
openssh_cert:
type: user
path: "{{ certificate_path }}"
public_key: "{{ public_key }}"
signing_key: "{{ signing_key }}"
signature_algorithm: rsa-sha2-256
valid_from: always
valid_to: forever
register: updated_signature_algorithm_idempotent
- name: Assert signature algorithm update is idempotent
assert:
that:
- updated_signature_algorithm_idempotent is not changed
- name: Generate cert with original signature algorithm
openssh_cert:
type: user
path: "{{ certificate_path }}"
public_key: "{{ public_key }}"
signing_key: "{{ signing_key }}"
signature_algorithm: ssh-rsa
valid_from: always
valid_to: forever
register: second_signature_algorithm
- name: Assert second signature algorithm update causes change
assert:
that:
- second_signature_algorithm is changed
- name: Omit signature algorithm
openssh_cert:
type: user
path: "{{ certificate_path }}"
public_key: "{{ public_key }}"
signing_key: "{{ signing_key }}"
valid_from: always
valid_to: forever
register: omitted_signature_algorithm
- name: Assert omitted_signature_algorithm does not cause change
assert:
that:
- omitted_signature_algorithm is not changed
- name: Revert to original certificate
openssh_cert:
type: user
path: "{{ certificate_path }}"
public_key: "{{ public_key }}"
signing_key: "{{ signing_key }}"
valid_from: always
valid_to: forever
regenerate: always
when: openssh_version is version("7.3", ">=")
- name: Generate cert with new signing key - name: Generate cert with new signing key
openssh_cert: openssh_cert:
type: user type: user

View File

@@ -12,7 +12,7 @@
type: user type: user
signing_key: "{{ signing_key }}" signing_key: "{{ signing_key }}"
public_key: "{{ public_key }}" public_key: "{{ public_key }}"
path: '{{ output_dir }}/id_cert_with_agent' path: '{{ remote_tmp_dir }}/id_cert_with_agent'
use_agent: true use_agent: true
valid_from: always valid_from: always
valid_to: forever valid_to: forever
@@ -33,7 +33,7 @@
type: user type: user
signing_key: "{{ signing_key }}" signing_key: "{{ signing_key }}"
public_key: "{{ public_key }}" public_key: "{{ public_key }}"
path: '{{ output_dir }}/id_cert_with_agent' path: '{{ remote_tmp_dir }}/id_cert_with_agent'
use_agent: true use_agent: true
valid_from: always valid_from: always
valid_to: forever valid_to: forever
@@ -44,7 +44,7 @@
type: user type: user
signing_key: "{{ signing_key }}" signing_key: "{{ signing_key }}"
public_key: "{{ public_key }}" public_key: "{{ public_key }}"
path: '{{ output_dir }}/id_cert_with_agent' path: '{{ remote_tmp_dir }}/id_cert_with_agent'
use_agent: true use_agent: true
valid_from: always valid_from: always
valid_to: forever valid_to: forever
@@ -54,7 +54,7 @@
type: user type: user
signing_key: "{{ signing_key }}" signing_key: "{{ signing_key }}"
public_key: "{{ public_key }}" public_key: "{{ public_key }}"
path: '{{ output_dir }}/id_cert_with_agent' path: '{{ remote_tmp_dir }}/id_cert_with_agent'
use_agent: true use_agent: true
valid_from: always valid_from: always
valid_to: forever valid_to: forever
@@ -71,7 +71,7 @@
type: user type: user
signing_key: "{{ signing_key }}" signing_key: "{{ signing_key }}"
public_key: "{{ public_key }}" public_key: "{{ public_key }}"
path: '{{ output_dir }}/id_cert_with_agent' path: '{{ remote_tmp_dir }}/id_cert_with_agent'
use_agent: true use_agent: true
valid_from: always valid_from: always
valid_to: forever valid_to: forever
@@ -80,4 +80,4 @@
- name: Remove certificate - name: Remove certificate
openssh_cert: openssh_cert:
state: absent state: absent
path: '{{ output_dir }}/id_cert_with_agent' path: '{{ remote_tmp_dir }}/id_cert_with_agent'

View File

@@ -1,4 +1,5 @@
dependencies: dependencies:
- setup_ssh_keygen - setup_ssh_keygen
- setup_openssl - setup_openssl
- setup_bcrypt - setup_bcrypt
- setup_remote_tmp_dir

View File

@@ -6,7 +6,7 @@
- name: Backend auto-detection test - name: Backend auto-detection test
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/auto_backend_key' path: '{{ remote_tmp_dir }}/auto_backend_key'
state: "{{ item }}" state: "{{ item }}"
loop: ['present', 'absent'] loop: ['present', 'absent']

View File

@@ -6,7 +6,7 @@
- name: "({{ backend }}) Generate key (check mode)" - name: "({{ backend }}) Generate key (check mode)"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/core" path: "{{ remote_tmp_dir }}/core"
size: 2048 size: 2048
backend: "{{ backend }}" backend: "{{ backend }}"
register: check_core_output register: check_core_output
@@ -14,14 +14,14 @@
- name: "({{ backend }}) Generate key" - name: "({{ backend }}) Generate key"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/core" path: "{{ remote_tmp_dir }}/core"
size: 2048 size: 2048
backend: "{{ backend }}" backend: "{{ backend }}"
register: core_output register: core_output
- name: "({{ backend }}) Generate key (check mode idempotent)" - name: "({{ backend }}) Generate key (check mode idempotent)"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/core" path: "{{ remote_tmp_dir }}/core"
size: 2048 size: 2048
backend: "{{ backend }}" backend: "{{ backend }}"
register: idempotency_check_core_output register: idempotency_check_core_output
@@ -29,7 +29,7 @@
- name: "({{ backend }}) Generate key (idempotent)" - name: "({{ backend }}) Generate key (idempotent)"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/core' path: '{{ remote_tmp_dir }}/core'
size: 2048 size: 2048
backend: "{{ backend }}" backend: "{{ backend }}"
register: idempotency_core_output register: idempotency_core_output
@@ -74,7 +74,7 @@
- core_output['type'] == 'rsa' - core_output['type'] == 'rsa'
- name: "({{ backend }}) Retrieve key size from 'ssh-keygen'" - name: "({{ backend }}) Retrieve key size from 'ssh-keygen'"
shell: "ssh-keygen -lf {{ output_dir }}/core | grep -o -E '^[0-9]+'" shell: "ssh-keygen -lf {{ remote_tmp_dir }}/core | grep -o -E '^[0-9]+'"
register: core_size_ssh_keygen register: core_size_ssh_keygen
- name: "({{ backend }}) Assert key size matches 'ssh-keygen' output" - name: "({{ backend }}) Assert key size matches 'ssh-keygen' output"
@@ -82,13 +82,18 @@
that: that:
- core_size_ssh_keygen.stdout == '2048' - core_size_ssh_keygen.stdout == '2048'
- name: "({{ backend }}) Read core.pub"
slurp:
src: '{{ remote_tmp_dir }}/core.pub'
register: slurp
- name: "({{ backend }}) Assert public key module return equal to the public key content" - name: "({{ backend }}) Assert public key module return equal to the public key content"
assert: assert:
that: that:
- "core_output.public_key == lookup('file', output_dir ~ '/core.pub').strip('\n')" - "core_output.public_key == (slurp.content | b64decode).strip('\n ')"
- name: "({{ backend }}) Remove key" - name: "({{ backend }}) Remove key"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/core' path: '{{ remote_tmp_dir }}/core'
backend: "{{ backend }}" backend: "{{ backend }}"
state: absent state: absent

View File

@@ -1,10 +1,10 @@
--- ---
- name: Generate a password protected key - name: Generate a password protected key
command: 'ssh-keygen -f {{ output_dir }}/password_protected -N {{ passphrase }}' command: 'ssh-keygen -f {{ remote_tmp_dir }}/password_protected -N {{ passphrase }}'
- name: Modify the password protected key with passphrase - name: Modify the password protected key with passphrase
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/password_protected' path: '{{ remote_tmp_dir }}/password_protected'
size: 1024 size: 1024
passphrase: "{{ passphrase }}" passphrase: "{{ passphrase }}"
backend: cryptography backend: cryptography
@@ -12,14 +12,14 @@
- name: Check password protected key idempotency - name: Check password protected key idempotency
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/password_protected' path: '{{ remote_tmp_dir }}/password_protected'
size: 1024 size: 1024
passphrase: "{{ passphrase }}" passphrase: "{{ passphrase }}"
backend: cryptography backend: cryptography
register: password_protected_idempotency_output register: password_protected_idempotency_output
- name: Ensure that ssh-keygen can read keys generated with passphrase - name: Ensure that ssh-keygen can read keys generated with passphrase
command: 'ssh-keygen -yf {{ output_dir }}/password_protected -P {{ passphrase }}' command: 'ssh-keygen -yf {{ remote_tmp_dir }}/password_protected -P {{ passphrase }}'
register: password_protected_ssh_keygen_output register: password_protected_ssh_keygen_output
- name: Check that password protected key with passphrase was regenerated - name: Check that password protected key with passphrase was regenerated
@@ -31,18 +31,18 @@
- name: Remove password protected key - name: Remove password protected key
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/password_protected' path: '{{ remote_tmp_dir }}/password_protected'
backend: cryptography backend: cryptography
state: absent state: absent
- name: Generate an unprotected key - name: Generate an unprotected key
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/unprotected' path: '{{ remote_tmp_dir }}/unprotected'
backend: cryptography backend: cryptography
- name: Modify unprotected key with passphrase - name: Modify unprotected key with passphrase
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/unprotected' path: '{{ remote_tmp_dir }}/unprotected'
size: 2048 size: 2048
passphrase: "{{ passphrase }}" passphrase: "{{ passphrase }}"
backend: cryptography backend: cryptography
@@ -51,7 +51,7 @@
- name: Modify unprotected key with passphrase (force) - name: Modify unprotected key with passphrase (force)
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/unprotected' path: '{{ remote_tmp_dir }}/unprotected'
size: 2048 size: 2048
passphrase: "{{ passphrase }}" passphrase: "{{ passphrase }}"
force: true force: true
@@ -66,16 +66,16 @@
- name: Remove unprotected key - name: Remove unprotected key
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/unprotected' path: '{{ remote_tmp_dir }}/unprotected'
backend: cryptography backend: cryptography
state: absent state: absent
- name: Generate PEM encoded key with passphrase - name: Generate PEM encoded key with passphrase
command: 'ssh-keygen -b 4096 -f {{ output_dir }}/pem_encoded -N {{ passphrase }} -m PEM' command: 'ssh-keygen -b 4096 -f {{ remote_tmp_dir }}/pem_encoded -N {{ passphrase }} -m PEM'
- name: Try to verify a PEM encoded key - name: Try to verify a PEM encoded key
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/pem_encoded' path: '{{ remote_tmp_dir }}/pem_encoded'
passphrase: "{{ passphrase }}" passphrase: "{{ passphrase }}"
backend: cryptography backend: cryptography
register: pem_encoded_output register: pem_encoded_output
@@ -87,6 +87,6 @@
- name: Remove PEM encoded key - name: Remove PEM encoded key
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/pem_encoded' path: '{{ remote_tmp_dir }}/pem_encoded'
backend: cryptography backend: cryptography
state: absent state: absent

View File

@@ -10,12 +10,12 @@
content: '' content: ''
mode: '0700' mode: '0700'
loop: loop:
- "{{ output_dir }}/broken" - "{{ remote_tmp_dir }}/broken"
- "{{ output_dir }}/broken.pub" - "{{ remote_tmp_dir }}/broken.pub"
- name: "({{ backend }}) Regenerate key - broken" - name: "({{ backend }}) Regenerate key - broken"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/broken" path: "{{ remote_tmp_dir }}/broken"
backend: "{{ backend }}" backend: "{{ backend }}"
register: broken_output register: broken_output
ignore_errors: true ignore_errors: true
@@ -28,7 +28,7 @@
- name: "({{ backend }}) Regenerate key with force - broken" - name: "({{ backend }}) Regenerate key with force - broken"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/broken" path: "{{ remote_tmp_dir }}/broken"
backend: "{{ backend }}" backend: "{{ backend }}"
force: true force: true
register: force_broken_output register: force_broken_output
@@ -40,24 +40,24 @@
- name: "({{ backend }}) Remove key - broken" - name: "({{ backend }}) Remove key - broken"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/broken" path: "{{ remote_tmp_dir }}/broken"
backend: "{{ backend }}" backend: "{{ backend }}"
state: absent state: absent
- name: "({{ backend }}) Generate key - write-only" - name: "({{ backend }}) Generate key - write-only"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/write-only" path: "{{ remote_tmp_dir }}/write-only"
mode: "0200" mode: "0200"
backend: "{{ backend }}" backend: "{{ backend }}"
- name: "({{ backend }}) Check private key status - write-only" - name: "({{ backend }}) Check private key status - write-only"
stat: stat:
path: '{{ output_dir }}/write-only' path: '{{ remote_tmp_dir }}/write-only'
register: write_only_private_key register: write_only_private_key
- name: "({{ backend }}) Check public key status - write-only" - name: "({{ backend }}) Check public key status - write-only"
stat: stat:
path: '{{ output_dir }}/write-only.pub' path: '{{ remote_tmp_dir }}/write-only.pub'
register: write_only_public_key register: write_only_public_key
- name: "({{ backend }}) Assert that private and public keys match permissions - write-only" - name: "({{ backend }}) Assert that private and public keys match permissions - write-only"
@@ -68,14 +68,14 @@
- name: "({{ backend }}) Regenerate key with force - write-only" - name: "({{ backend }}) Regenerate key with force - write-only"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/write-only" path: "{{ remote_tmp_dir }}/write-only"
backend: "{{ backend }}" backend: "{{ backend }}"
force: true force: true
register: write_only_output register: write_only_output
- name: "({{ backend }}) Check private key status after regeneration - write-only" - name: "({{ backend }}) Check private key status after regeneration - write-only"
stat: stat:
path: '{{ output_dir }}/write-only' path: '{{ remote_tmp_dir }}/write-only'
register: write_only_private_key_after register: write_only_private_key_after
- name: "({{ backend }}) Assert key is regenerated - write-only" - name: "({{ backend }}) Assert key is regenerated - write-only"
@@ -90,16 +90,16 @@
- name: "({{ backend }}) Remove key - write-only" - name: "({{ backend }}) Remove key - write-only"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/write-only" path: "{{ remote_tmp_dir }}/write-only"
backend: "{{ backend }}" backend: "{{ backend }}"
state: absent state: absent
- name: "({{ backend }}) Generate key with ssh-keygen - password_protected" - name: "({{ backend }}) Generate key with ssh-keygen - password_protected"
command: "ssh-keygen -f {{ output_dir }}/password_protected -N {{ passphrase }}" command: "ssh-keygen -f {{ remote_tmp_dir }}/password_protected -N {{ passphrase }}"
- name: "({{ backend }}) Modify key - password_protected" - name: "({{ backend }}) Modify key - password_protected"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/password_protected" path: "{{ remote_tmp_dir }}/password_protected"
size: 2048 size: 2048
backend: "{{ backend }}" backend: "{{ backend }}"
register: password_protected_output register: password_protected_output
@@ -113,7 +113,7 @@
- name: "({{ backend }}) Modify key with 'force=true' - password_protected" - name: "({{ backend }}) Modify key with 'force=true' - password_protected"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/password_protected" path: "{{ remote_tmp_dir }}/password_protected"
size: 2048 size: 2048
backend: "{{ backend }}" backend: "{{ backend }}"
force: true force: true
@@ -126,6 +126,6 @@
- name: "({{ backend }}) Remove key - password_protected" - name: "({{ backend }}) Remove key - password_protected"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/password_protected" path: "{{ remote_tmp_dir }}/password_protected"
backend: "{{ backend }}" backend: "{{ backend }}"
state: absent state: absent

View File

@@ -12,13 +12,13 @@
- name: "({{ backend }}) Generate keys with default size - size" - name: "({{ backend }}) Generate keys with default size - size"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/default_size_{{ item }}" path: "{{ remote_tmp_dir }}/default_size_{{ item }}"
type: "{{ item }}" type: "{{ item }}"
backend: "{{ backend }}" backend: "{{ backend }}"
loop: "{{ key_types }}" loop: "{{ key_types }}"
- name: "({{ backend }}) Retrieve key size from 'ssh-keygen' - size" - name: "({{ backend }}) Retrieve key size from 'ssh-keygen' - size"
shell: "ssh-keygen -lf {{ output_dir }}/default_size_{{ item }} | grep -o -E '^[0-9]+'" shell: "ssh-keygen -lf {{ remote_tmp_dir }}/default_size_{{ item }} | grep -o -E '^[0-9]+'"
loop: "{{ key_types }}" loop: "{{ key_types }}"
register: key_size_output register: key_size_output
@@ -31,19 +31,19 @@
- name: "({{ backend }}) Remove keys - size" - name: "({{ backend }}) Remove keys - size"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/default_size_{{ item }}" path: "{{ remote_tmp_dir }}/default_size_{{ item }}"
state: absent state: absent
loop: "{{ key_types }}" loop: "{{ key_types }}"
- block: - block:
- name: "({{ backend }}) Generate ed25519 key with default size - size" - name: "({{ backend }}) Generate ed25519 key with default size - size"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/default_size_ed25519" path: "{{ remote_tmp_dir }}/default_size_ed25519"
type: ed25519 type: ed25519
backend: "{{ backend }}" backend: "{{ backend }}"
- name: "({{ backend }}) Retrieve ed25519 key size from 'ssh-keygen' - size" - name: "({{ backend }}) Retrieve ed25519 key size from 'ssh-keygen' - size"
shell: "ssh-keygen -lf {{ output_dir }}/default_size_ed25519 | grep -o -E '^[0-9]+'" shell: "ssh-keygen -lf {{ remote_tmp_dir }}/default_size_ed25519 | grep -o -E '^[0-9]+'"
register: ed25519_key_size_output register: ed25519_key_size_output
- name: "({{ backend }}) Assert ed25519 key size matches default size - size" - name: "({{ backend }}) Assert ed25519 key size matches default size - size"
@@ -53,20 +53,20 @@
- name: "({{ backend }}) Remove ed25519 key - size" - name: "({{ backend }}) Remove ed25519 key - size"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/default_size_ed25519" path: "{{ remote_tmp_dir }}/default_size_ed25519"
state: absent state: absent
# Support for ed25519 keys was added in OpenSSH 6.5 # Support for ed25519 keys was added in OpenSSH 6.5
when: not (backend == 'opensshbin' and openssh_version is version('6.5', '<')) when: not (backend == 'opensshbin' and openssh_version is version('6.5', '<'))
- name: "({{ backend }}) Generate key - force" - name: "({{ backend }}) Generate key - force"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/force" path: "{{ remote_tmp_dir }}/force"
type: rsa type: rsa
backend: "{{ backend }}" backend: "{{ backend }}"
- name: "({{ backend }}) Regenerate key - force" - name: "({{ backend }}) Regenerate key - force"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/force" path: "{{ remote_tmp_dir }}/force"
type: rsa type: rsa
force: true force: true
backend: "{{ backend }}" backend: "{{ backend }}"
@@ -79,20 +79,20 @@
- name: "({{ backend }}) Remove key - force" - name: "({{ backend }}) Remove key - force"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/force" path: "{{ remote_tmp_dir }}/force"
state: absent state: absent
backend: "{{ backend }}" backend: "{{ backend }}"
- name: "({{ backend }}) Generate key - comment" - name: "({{ backend }}) Generate key - comment"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/comment" path: "{{ remote_tmp_dir }}/comment"
comment: "test@comment" comment: "test@comment"
backend: "{{ backend }}" backend: "{{ backend }}"
register: comment_output register: comment_output
- name: "({{ backend }}) Modify comment - comment" - name: "({{ backend }}) Modify comment - comment"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/comment" path: "{{ remote_tmp_dir }}/comment"
comment: "test_modified@comment" comment: "test_modified@comment"
backend: "{{ backend }}" backend: "{{ backend }}"
register: modified_comment_output register: modified_comment_output
@@ -112,6 +112,6 @@
- name: "({{ backend }}) Remove key - comment" - name: "({{ backend }}) Remove key - comment"
openssh_keypair: openssh_keypair:
path: "{{ output_dir }}/comment" path: "{{ remote_tmp_dir }}/comment"
state: absent state: absent
backend: "{{ backend }}" backend: "{{ backend }}"

View File

@@ -5,27 +5,33 @@
#################################################################### ####################################################################
# Ensures no conflicts from previous test runs # Ensures no conflicts from previous test runs
- name: "({{ backend }}) Find old test artifacts"
ansible.builtin.find:
paths: "{{ remote_tmp_dir }}"
patterns:
- "regenerate*"
register: old_test_artifacts
- name: "({{ backend }}) Cleanup Output Directory" - name: "({{ backend }}) Cleanup Output Directory"
ansible.builtin.file: ansible.builtin.file:
path: "{{ item }}" path: "{{ item.path }}"
state: absent state: absent
with_fileglob: loop: "{{ old_test_artifacts.files }}"
- "{{ output_dir }}/regenerate*"
- name: "({{ backend }}) Regenerate - setup simple keys" - name: "({{ backend }}) Regenerate - setup simple keys"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: rsa type: rsa
size: 1024 size: 1024
backend: "{{ backend }}" backend: "{{ backend }}"
loop: "{{ regenerate_values }}" loop: "{{ regenerate_values }}"
- name: "({{ backend }}) Regenerate - setup password protected keys" - name: "({{ backend }}) Regenerate - setup password protected keys"
command: 'ssh-keygen -f {{ output_dir }}/regenerate-b-{{ item }} -N {{ passphrase }}' command: 'ssh-keygen -f {{ remote_tmp_dir }}/regenerate-b-{{ item }} -N {{ passphrase }}'
loop: "{{ regenerate_values }}" loop: "{{ regenerate_values }}"
- name: "({{ backend }}) Regenerate - setup broken keys" - name: "({{ backend }}) Regenerate - setup broken keys"
copy: copy:
dest: '{{ output_dir }}/regenerate-c-{{ item.0 }}{{ item.1 }}' dest: '{{ remote_tmp_dir }}/regenerate-c-{{ item.0 }}{{ item.1 }}'
content: 'broken key' content: 'broken key'
mode: '0700' mode: '0700'
with_nested: with_nested:
@@ -33,12 +39,12 @@
- [ '', '.pub' ] - [ '', '.pub' ]
- name: "({{ backend }}) Regenerate - setup password protected keys for passphrse test" - name: "({{ backend }}) Regenerate - setup password protected keys for passphrse test"
command: 'ssh-keygen -f {{ output_dir }}/regenerate-d-{{ item }} -N {{ passphrase }}' command: 'ssh-keygen -f {{ remote_tmp_dir }}/regenerate-d-{{ item }} -N {{ passphrase }}'
loop: "{{ regenerate_values }}" loop: "{{ regenerate_values }}"
- name: "({{ backend }}) Regenerate - modify broken keys (check mode)" - name: "({{ backend }}) Regenerate - modify broken keys (check mode)"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-c-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-c-{{ item }}'
type: rsa type: rsa
size: 1024 size: 1024
regenerate: '{{ item }}' regenerate: '{{ item }}'
@@ -60,7 +66,7 @@
- name: "({{ backend }}) Regenerate - modify broken keys" - name: "({{ backend }}) Regenerate - modify broken keys"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-c-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-c-{{ item }}'
type: rsa type: rsa
size: 1024 size: 1024
regenerate: '{{ item }}' regenerate: '{{ item }}'
@@ -81,7 +87,7 @@
- name: "({{ backend }}) Regenerate - modify password protected keys (check mode)" - name: "({{ backend }}) Regenerate - modify password protected keys (check mode)"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-b-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-b-{{ item }}'
type: rsa type: rsa
size: 1024 size: 1024
regenerate: '{{ item }}' regenerate: '{{ item }}'
@@ -103,7 +109,7 @@
- name: "({{ backend }}) Regenerate - modify password protected keys with passphrase (check mode)" - name: "({{ backend }}) Regenerate - modify password protected keys with passphrase (check mode)"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-b-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-b-{{ item }}'
type: rsa type: rsa
size: 1024 size: 1024
passphrase: "{{ passphrase }}" passphrase: "{{ passphrase }}"
@@ -127,7 +133,7 @@
- name: "({{ backend }}) Regenerate - modify password protected keys" - name: "({{ backend }}) Regenerate - modify password protected keys"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-b-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-b-{{ item }}'
type: rsa type: rsa
size: 1024 size: 1024
regenerate: '{{ item }}' regenerate: '{{ item }}'
@@ -148,7 +154,7 @@
- name: "({{ backend }}) Regenerate - modify password protected keys with passphrase" - name: "({{ backend }}) Regenerate - modify password protected keys with passphrase"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-d-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-d-{{ item }}'
type: rsa type: rsa
size: 1024 size: 1024
passphrase: "{{ passphrase }}" passphrase: "{{ passphrase }}"
@@ -171,7 +177,7 @@
- name: "({{ backend }}) Regenerate - not modify regular keys (check mode)" - name: "({{ backend }}) Regenerate - not modify regular keys (check mode)"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: rsa type: rsa
size: 1024 size: 1024
regenerate: '{{ item }}' regenerate: '{{ item }}'
@@ -189,7 +195,7 @@
- name: "({{ backend }}) Regenerate - not modify regular keys" - name: "({{ backend }}) Regenerate - not modify regular keys"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: rsa type: rsa
size: 1024 size: 1024
regenerate: '{{ item }}' regenerate: '{{ item }}'
@@ -206,7 +212,7 @@
- name: "({{ backend }}) Regenerate - adjust key size (check mode)" - name: "({{ backend }}) Regenerate - adjust key size (check mode)"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: rsa type: rsa
size: 1048 size: 1048
regenerate: '{{ item }}' regenerate: '{{ item }}'
@@ -226,7 +232,7 @@
- name: "({{ backend }}) Regenerate - adjust key size" - name: "({{ backend }}) Regenerate - adjust key size"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: rsa type: rsa
size: 1048 size: 1048
regenerate: '{{ item }}' regenerate: '{{ item }}'
@@ -245,8 +251,8 @@
- name: "({{ backend }}) Regenerate - redistribute keys" - name: "({{ backend }}) Regenerate - redistribute keys"
copy: copy:
src: '{{ output_dir }}/regenerate-a-always{{ item.1 }}' src: '{{ remote_tmp_dir }}/regenerate-a-always{{ item.1 }}'
dest: '{{ output_dir }}/regenerate-a-{{ item.0 }}{{ item.1 }}' dest: '{{ remote_tmp_dir }}/regenerate-a-{{ item.0 }}{{ item.1 }}'
remote_src: true remote_src: true
with_nested: with_nested:
- "{{ regenerate_values }}" - "{{ regenerate_values }}"
@@ -255,7 +261,7 @@
- name: "({{ backend }}) Regenerate - adjust key type (check mode)" - name: "({{ backend }}) Regenerate - adjust key type (check mode)"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: dsa type: dsa
size: 1024 size: 1024
regenerate: '{{ item }}' regenerate: '{{ item }}'
@@ -275,7 +281,7 @@
- name: "({{ backend }}) Regenerate - adjust key type" - name: "({{ backend }}) Regenerate - adjust key type"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: dsa type: dsa
size: 1024 size: 1024
regenerate: '{{ item }}' regenerate: '{{ item }}'
@@ -294,8 +300,8 @@
- name: "({{ backend }}) Regenerate - redistribute keys" - name: "({{ backend }}) Regenerate - redistribute keys"
copy: copy:
src: '{{ output_dir }}/regenerate-a-always{{ item.1 }}' src: '{{ remote_tmp_dir }}/regenerate-a-always{{ item.1 }}'
dest: '{{ output_dir }}/regenerate-a-{{ item.0 }}{{ item.1 }}' dest: '{{ remote_tmp_dir }}/regenerate-a-{{ item.0 }}{{ item.1 }}'
remote_src: true remote_src: true
with_nested: with_nested:
- "{{ regenerate_values }}" - "{{ regenerate_values }}"
@@ -304,7 +310,7 @@
- name: "({{ backend }}) Regenerate - adjust comment (check mode)" - name: "({{ backend }}) Regenerate - adjust comment (check mode)"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: dsa type: dsa
size: 1024 size: 1024
comment: test comment comment: test comment
@@ -320,7 +326,7 @@
- name: "({{ backend }}) Regenerate - adjust comment" - name: "({{ backend }}) Regenerate - adjust comment"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}' path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: dsa type: dsa
size: 1024 size: 1024
comment: test comment comment: test comment

View File

@@ -6,36 +6,36 @@
- name: "({{ backend }}) Generate key" - name: "({{ backend }}) Generate key"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/removed' path: '{{ remote_tmp_dir }}/removed'
backend: "{{ backend }}" backend: "{{ backend }}"
state: present state: present
- name: "({{ backend }}) Generate key (idempotency)" - name: "({{ backend }}) Generate key (idempotency)"
openssh_keypair: openssh_keypair:
path: '{{ output_dir }}/removed' path: '{{ remote_tmp_dir }}/removed'
backend: "{{ backend }}" backend: "{{ backend }}"
state: present state: present
- name: "({{ backend }}) Remove key" - name: "({{ backend }}) Remove key"
openssh_keypair: openssh_keypair:
state: absent state: absent
path: '{{ output_dir }}/removed' path: '{{ remote_tmp_dir }}/removed'
backend: "{{ backend }}" backend: "{{ backend }}"
- name: "({{ backend }}) Remove key (idempotency)" - name: "({{ backend }}) Remove key (idempotency)"
openssh_keypair: openssh_keypair:
state: absent state: absent
path: '{{ output_dir }}/removed' path: '{{ remote_tmp_dir }}/removed'
backend: "{{ backend }}" backend: "{{ backend }}"
- name: "({{ backend }}) Check private key status" - name: "({{ backend }}) Check private key status"
stat: stat:
path: '{{ output_dir }}/removed' path: '{{ remote_tmp_dir }}/removed'
register: removed_private_key register: removed_private_key
- name: "({{ backend }}) Check public key status" - name: "({{ backend }}) Check public key status"
stat: stat:
path: '{{ output_dir }}/removed.pub' path: '{{ remote_tmp_dir }}/removed.pub'
register: removed_public_key register: removed_public_key
- name: "({{ backend }}) Assert key pair files are removed" - name: "({{ backend }}) Assert key pair files are removed"

View File

@@ -1,2 +1,3 @@
shippable/cloud/group1
shippable/posix/group1 shippable/posix/group1
destructive destructive

View File

@@ -1,3 +1,4 @@
dependencies: dependencies:
- setup_openssl - setup_openssl
- setup_pyopenssl - setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -1,13 +1,13 @@
--- ---
- name: "({{ select_crypto_backend }}) Generate privatekey" - name: "({{ select_crypto_backend }}) Generate privatekey"
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/privatekey.pem' path: '{{ remote_tmp_dir }}/privatekey.pem'
size: '{{ default_rsa_key_size }}' size: '{{ default_rsa_key_size }}'
- name: "({{ select_crypto_backend }}) Generate CSR (check mode)" - name: "({{ select_crypto_backend }}) Generate CSR (check mode)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr.csr' path: '{{ remote_tmp_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -17,8 +17,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR" - name: "({{ select_crypto_backend }}) Generate CSR"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr.csr' path: '{{ remote_tmp_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -27,8 +27,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent)" - name: "({{ select_crypto_backend }}) Generate CSR (idempotent)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr.csr' path: '{{ remote_tmp_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -37,8 +37,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent, check mode)" - name: "({{ select_crypto_backend }}) Generate CSR (idempotent, check mode)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr.csr' path: '{{ remote_tmp_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -48,8 +48,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR without SAN (check mode)" - name: "({{ select_crypto_backend }}) Generate CSR without SAN (check mode)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr-nosan.csr' path: '{{ remote_tmp_dir }}/csr-nosan.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
useCommonNameForSAN: no useCommonNameForSAN: no
@@ -59,8 +59,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR without SAN" - name: "({{ select_crypto_backend }}) Generate CSR without SAN"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr-nosan.csr' path: '{{ remote_tmp_dir }}/csr-nosan.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
useCommonNameForSAN: no useCommonNameForSAN: no
@@ -69,8 +69,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR without SAN (idempotent)" - name: "({{ select_crypto_backend }}) Generate CSR without SAN (idempotent)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr-nosan.csr' path: '{{ remote_tmp_dir }}/csr-nosan.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
useCommonNameForSAN: no useCommonNameForSAN: no
@@ -79,8 +79,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR without SAN (idempotent, check mode)" - name: "({{ select_crypto_backend }}) Generate CSR without SAN (idempotent, check mode)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr-nosan.csr' path: '{{ remote_tmp_dir }}/csr-nosan.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
useCommonNameForSAN: no useCommonNameForSAN: no
@@ -94,8 +94,8 @@
# and vice-versa for biometricInfo # and vice-versa for biometricInfo
- name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU" - name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ku_xku.csr' path: '{{ remote_tmp_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
CN: www.ansible.com CN: www.ansible.com
keyUsage: keyUsage:
@@ -110,8 +110,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU (test idempotency)" - name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU (test idempotency)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ku_xku.csr' path: '{{ remote_tmp_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: 'www.ansible.com' commonName: 'www.ansible.com'
keyUsage: keyUsage:
@@ -127,8 +127,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU (test XKU change)" - name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU (test XKU change)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ku_xku.csr' path: '{{ remote_tmp_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: 'www.ansible.com' commonName: 'www.ansible.com'
keyUsage: keyUsage:
@@ -143,8 +143,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU (test KU change)" - name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU (test KU change)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ku_xku.csr' path: '{{ remote_tmp_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: 'www.ansible.com' commonName: 'www.ansible.com'
keyUsage: keyUsage:
@@ -158,15 +158,15 @@
- name: "({{ select_crypto_backend }}) Generate CSR with old API" - name: "({{ select_crypto_backend }}) Generate CSR with old API"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_oldapi.csr' path: '{{ remote_tmp_dir }}/csr_oldapi.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate CSR with invalid SAN (1/2)" - name: "({{ select_crypto_backend }}) Generate CSR with invalid SAN (1/2)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csrinvsan.csr' path: '{{ remote_tmp_dir }}/csrinvsan.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject_alt_name: invalid-san.example.com subject_alt_name: invalid-san.example.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: generate_csr_invalid_san register: generate_csr_invalid_san
@@ -174,8 +174,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with invalid SAN (2/2)" - name: "({{ select_crypto_backend }}) Generate CSR with invalid SAN (2/2)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csrinvsan2.csr' path: '{{ remote_tmp_dir }}/csrinvsan2.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject_alt_name: "DNS:system:kube-controller-manager" subject_alt_name: "DNS:system:kube-controller-manager"
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: generate_csr_invalid_san_2 register: generate_csr_invalid_san_2
@@ -183,16 +183,16 @@
- name: "({{ select_crypto_backend }}) Generate CSR with OCSP Must Staple" - name: "({{ select_crypto_backend }}) Generate CSR with OCSP Must Staple"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ocsp.csr' path: '{{ remote_tmp_dir }}/csr_ocsp.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject_alt_name: "DNS:www.ansible.com" subject_alt_name: "DNS:www.ansible.com"
ocsp_must_staple: true ocsp_must_staple: true
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate CSR with OCSP Must Staple (test idempotency)" - name: "({{ select_crypto_backend }}) Generate CSR with OCSP Must Staple (test idempotency)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ocsp.csr' path: '{{ remote_tmp_dir }}/csr_ocsp.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject_alt_name: "DNS:www.ansible.com" subject_alt_name: "DNS:www.ansible.com"
ocsp_must_staple: true ocsp_must_staple: true
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -200,22 +200,22 @@
- name: "({{ select_crypto_backend }}) Generate ECC privatekey" - name: "({{ select_crypto_backend }}) Generate ECC privatekey"
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/privatekey2.pem' path: '{{ remote_tmp_dir }}/privatekey2.pem'
type: ECC type: ECC
curve: secp384r1 curve: secp384r1
- name: "({{ select_crypto_backend }}) Generate CSR with ECC privatekey" - name: "({{ select_crypto_backend }}) Generate CSR with ECC privatekey"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr2.csr' path: '{{ remote_tmp_dir }}/csr2.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate CSR with text common name" - name: "({{ select_crypto_backend }}) Generate CSR with text common name"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr3.csr' path: '{{ remote_tmp_dir }}/csr3.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
subject: subject:
commonName: This is for Ansible commonName: This is for Ansible
useCommonNameForSAN: no useCommonNameForSAN: no
@@ -223,24 +223,24 @@
- name: "({{ select_crypto_backend }}) Generate CSR with country name" - name: "({{ select_crypto_backend }}) Generate CSR with country name"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr4.csr' path: '{{ remote_tmp_dir }}/csr4.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
country_name: de country_name: de
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: country_idempotent_1 register: country_idempotent_1
- name: "({{ select_crypto_backend }}) Generate CSR with country name (idempotent)" - name: "({{ select_crypto_backend }}) Generate CSR with country name (idempotent)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr4.csr' path: '{{ remote_tmp_dir }}/csr4.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
country_name: de country_name: de
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: country_idempotent_2 register: country_idempotent_2
- name: "({{ select_crypto_backend }}) Generate CSR with country name (idempotent 2)" - name: "({{ select_crypto_backend }}) Generate CSR with country name (idempotent 2)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr4.csr' path: '{{ remote_tmp_dir }}/csr4.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
subject: subject:
C: de C: de
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -248,8 +248,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with country name (bad country name)" - name: "({{ select_crypto_backend }}) Generate CSR with country name (bad country name)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr4.csr' path: '{{ remote_tmp_dir }}/csr4.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
subject: subject:
C: dex C: dex
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -258,7 +258,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey with password" - name: "({{ select_crypto_backend }}) Generate privatekey with password"
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem' path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2 passphrase: hunter2
cipher: auto cipher: auto
select_crypto_backend: cryptography select_crypto_backend: cryptography
@@ -266,16 +266,16 @@
- name: "({{ select_crypto_backend }}) Generate CSR with privatekey passphrase" - name: "({{ select_crypto_backend }}) Generate CSR with privatekey passphrase"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_pw.csr' path: '{{ remote_tmp_dir }}/csr_pw.csr'
privatekey_path: '{{ output_dir }}/privatekeypw.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: hunter2 privatekey_passphrase: hunter2
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: passphrase_1 register: passphrase_1
- name: "({{ select_crypto_backend }}) Generate CSR (failed passphrase 1)" - name: "({{ select_crypto_backend }}) Generate CSR (failed passphrase 1)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_pw1.csr' path: '{{ remote_tmp_dir }}/csr_pw1.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
privatekey_passphrase: hunter2 privatekey_passphrase: hunter2
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes ignore_errors: yes
@@ -283,8 +283,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR (failed passphrase 2)" - name: "({{ select_crypto_backend }}) Generate CSR (failed passphrase 2)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_pw2.csr' path: '{{ remote_tmp_dir }}/csr_pw2.csr'
privatekey_path: '{{ output_dir }}/privatekeypw.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: wrong_password privatekey_passphrase: wrong_password
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes ignore_errors: yes
@@ -292,20 +292,20 @@
- name: "({{ select_crypto_backend }}) Generate CSR (failed passphrase 3)" - name: "({{ select_crypto_backend }}) Generate CSR (failed passphrase 3)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_pw3.csr' path: '{{ remote_tmp_dir }}/csr_pw3.csr'
privatekey_path: '{{ output_dir }}/privatekeypw.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes ignore_errors: yes
register: passphrase_error_3 register: passphrase_error_3
- name: "({{ select_crypto_backend }}) Create broken CSR" - name: "({{ select_crypto_backend }}) Create broken CSR"
copy: copy:
dest: "{{ output_dir }}/csrbroken.csr" dest: "{{ remote_tmp_dir }}/csrbroken.csr"
content: "broken" content: "broken"
- name: "({{ select_crypto_backend }}) Regenerate broken CSR" - name: "({{ select_crypto_backend }}) Regenerate broken CSR"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csrbroken.csr' path: '{{ remote_tmp_dir }}/csrbroken.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
subject: subject:
commonName: This is for Ansible commonName: This is for Ansible
useCommonNameForSAN: no useCommonNameForSAN: no
@@ -314,8 +314,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR" - name: "({{ select_crypto_backend }}) Generate CSR"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_backup.csr' path: '{{ remote_tmp_dir }}/csr_backup.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
backup: yes backup: yes
@@ -323,8 +323,8 @@
register: csr_backup_1 register: csr_backup_1
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent)" - name: "({{ select_crypto_backend }}) Generate CSR (idempotent)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_backup.csr' path: '{{ remote_tmp_dir }}/csr_backup.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
backup: yes backup: yes
@@ -332,8 +332,8 @@
register: csr_backup_2 register: csr_backup_2
- name: "({{ select_crypto_backend }}) Generate CSR (change)" - name: "({{ select_crypto_backend }}) Generate CSR (change)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_backup.csr' path: '{{ remote_tmp_dir }}/csr_backup.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: ansible.com commonName: ansible.com
backup: yes backup: yes
@@ -341,7 +341,7 @@
register: csr_backup_3 register: csr_backup_3
- name: "({{ select_crypto_backend }}) Generate CSR (remove)" - name: "({{ select_crypto_backend }}) Generate CSR (remove)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_backup.csr' path: '{{ remote_tmp_dir }}/csr_backup.csr'
state: absent state: absent
backup: yes backup: yes
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -349,7 +349,7 @@
register: csr_backup_4 register: csr_backup_4
- name: "({{ select_crypto_backend }}) Generate CSR (remove, idempotent)" - name: "({{ select_crypto_backend }}) Generate CSR (remove, idempotent)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_backup.csr' path: '{{ remote_tmp_dir }}/csr_backup.csr'
state: absent state: absent
backup: yes backup: yes
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -357,8 +357,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier" - name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ski.csr' path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
subject_key_identifier: "00:11:22:33" subject_key_identifier: "00:11:22:33"
@@ -368,8 +368,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (idempotency)" - name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (idempotency)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ski.csr' path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
subject_key_identifier: "00:11:22:33" subject_key_identifier: "00:11:22:33"
@@ -379,8 +379,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (change)" - name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (change)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ski.csr' path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
subject_key_identifier: "44:55:66:77:88" subject_key_identifier: "44:55:66:77:88"
@@ -390,8 +390,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (auto-create)" - name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (auto-create)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ski.csr' path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
create_subject_key_identifier: yes create_subject_key_identifier: yes
@@ -401,8 +401,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (auto-create idempotency)" - name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (auto-create idempotency)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ski.csr' path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
create_subject_key_identifier: yes create_subject_key_identifier: yes
@@ -412,8 +412,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (remove)" - name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (remove)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_ski.csr' path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -422,8 +422,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier" - name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_aki.csr' path: '{{ remote_tmp_dir }}/csr_aki.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
authority_key_identifier: "00:11:22:33" authority_key_identifier: "00:11:22:33"
@@ -433,8 +433,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier (idempotency)" - name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier (idempotency)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_aki.csr' path: '{{ remote_tmp_dir }}/csr_aki.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
authority_key_identifier: "00:11:22:33" authority_key_identifier: "00:11:22:33"
@@ -444,8 +444,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier (change)" - name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier (change)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_aki.csr' path: '{{ remote_tmp_dir }}/csr_aki.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
authority_key_identifier: "44:55:66:77:88" authority_key_identifier: "44:55:66:77:88"
@@ -455,8 +455,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier (remove)" - name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier (remove)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_aki.csr' path: '{{ remote_tmp_dir }}/csr_aki.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -465,8 +465,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number" - name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_acisn.csr' path: '{{ remote_tmp_dir }}/csr_acisn.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
authority_cert_issuer: authority_cert_issuer:
@@ -479,8 +479,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (idempotency)" - name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (idempotency)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_acisn.csr' path: '{{ remote_tmp_dir }}/csr_acisn.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
authority_cert_issuer: authority_cert_issuer:
@@ -493,8 +493,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (change issuer)" - name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (change issuer)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_acisn.csr' path: '{{ remote_tmp_dir }}/csr_acisn.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
authority_cert_issuer: authority_cert_issuer:
@@ -507,8 +507,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (change serial number)" - name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (change serial number)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_acisn.csr' path: '{{ remote_tmp_dir }}/csr_acisn.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
authority_cert_issuer: authority_cert_issuer:
@@ -521,8 +521,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (remove)" - name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (remove)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_acisn.csr' path: '{{ remote_tmp_dir }}/csr_acisn.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
when: select_crypto_backend != 'pyopenssl' when: select_crypto_backend != 'pyopenssl'
@@ -530,20 +530,20 @@
- name: "({{ select_crypto_backend }}) Generate CSR with everything" - name: "({{ select_crypto_backend }}) Generate CSR with everything"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_everything.csr' path: '{{ remote_tmp_dir }}/csr_everything.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.example.com commonName: www.example.com
C: de C: de
L: Somewhere L: Somewhere
ST: Zurich ST: Zürich
streetAddress: Welcome Street streetAddress: Welcome Street N° 5
O: Ansible O: Ansiblé
organizationalUnitName: Crypto Department organizationalUnitName: Crÿpto Depârtment
serialNumber: "1234" serialNumber: "1234"
SN: Last Name SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
GN: First Name GN: First Name
title: Chief title: Chïeff
pseudonym: test pseudonym: test
UID: asdf UID: asdf
emailAddress: test@example.com emailAddress: test@example.com
@@ -638,20 +638,20 @@
- name: "({{ select_crypto_backend }}) Generate CSR with everything (idempotent, check mode)" - name: "({{ select_crypto_backend }}) Generate CSR with everything (idempotent, check mode)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_everything.csr' path: '{{ remote_tmp_dir }}/csr_everything.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.example.com CN: www.example.com
C: de countryName: de
L: Somewhere L: Somewhere
ST: Zurich ST: Zürich
streetAddress: Welcome Street streetAddress: Welcome Street N° 5
O: Ansible organizationName: Ansiblé
organizationalUnitName: Crypto Department organizationalUnitName: Crÿpto Depârtment
serialNumber: "1234" serialNumber: "1234"
SN: Last Name SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
GN: First Name GN: First Name
title: Chief title: Chïeff
pseudonym: test pseudonym: test
UID: asdf UID: asdf
emailAddress: test@example.com emailAddress: test@example.com
@@ -747,20 +747,20 @@
- name: "({{ select_crypto_backend }}) Generate CSR with everything (idempotent)" - name: "({{ select_crypto_backend }}) Generate CSR with everything (idempotent)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_everything.csr' path: '{{ remote_tmp_dir }}/csr_everything.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.example.com CN: www.example.com
C: de countryName: de
L: Somewhere L: Somewhere
ST: Zurich ST: Zürich
streetAddress: Welcome Street streetAddress: Welcome Street N° 5
O: Ansible organizationName: Ansiblé
organizationalUnitName: Crypto Department organizationalUnitName: Crÿpto Depârtment
serialNumber: "1234" serialNumber: "1234"
SN: Last Name SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
GN: First Name GN: First Name
title: Chief title: Chïeff
pseudonym: test pseudonym: test
UID: asdf UID: asdf
emailAddress: test@example.com emailAddress: test@example.com
@@ -855,7 +855,7 @@
- name: "({{ select_crypto_backend }}) Get info from CSR with everything" - name: "({{ select_crypto_backend }}) Get info from CSR with everything"
community.crypto.openssl_csr_info: community.crypto.openssl_csr_info:
path: '{{ output_dir }}/csr_everything.csr' path: '{{ remote_tmp_dir }}/csr_everything.csr'
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: everything_info register: everything_info
@@ -863,7 +863,7 @@
block: block:
- name: "({{ select_crypto_backend }}) Generate privatekeys" - name: "({{ select_crypto_backend }}) Generate privatekeys"
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/privatekey_{{ item }}.pem' path: '{{ remote_tmp_dir }}/privatekey_{{ item }}.pem'
type: '{{ item }}' type: '{{ item }}'
loop: loop:
- Ed25519 - Ed25519
@@ -877,8 +877,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR" - name: "({{ select_crypto_backend }}) Generate CSR"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_{{ item }}.csr' path: '{{ remote_tmp_dir }}/csr_{{ item }}.csr'
privatekey_path: '{{ output_dir }}/privatekey_{{ item }}.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey_{{ item }}.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -890,8 +890,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent)" - name: "({{ select_crypto_backend }}) Generate CSR (idempotent)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_{{ item }}.csr' path: '{{ remote_tmp_dir }}/csr_{{ item }}.csr'
privatekey_path: '{{ output_dir }}/privatekey_{{ item }}.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey_{{ item }}.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -907,8 +907,8 @@
block: block:
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints" - name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_crl_d_e.csr' path: '{{ remote_tmp_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
crl_distribution_points: crl_distribution_points:
@@ -930,8 +930,8 @@
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints (idempotence)" - name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints (idempotence)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_crl_d_e.csr' path: '{{ remote_tmp_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
crl_distribution_points: crl_distribution_points:
@@ -953,8 +953,8 @@
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints (change)" - name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints (change)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_crl_d_e.csr' path: '{{ remote_tmp_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
crl_distribution_points: crl_distribution_points:
@@ -975,8 +975,8 @@
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints (no endpoints)" - name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints (no endpoints)"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_crl_d_e.csr' path: '{{ remote_tmp_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -984,8 +984,8 @@
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints" - name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints"
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_crl_d_e.csr' path: '{{ remote_tmp_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
crl_distribution_points: crl_distribution_points:

View File

@@ -6,12 +6,12 @@
- name: Prepare private key for backend autodetection test - name: Prepare private key for backend autodetection test
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/privatekey_backend_selection.pem' path: '{{ remote_tmp_dir }}/privatekey_backend_selection.pem'
size: '{{ default_rsa_key_size }}' size: '{{ default_rsa_key_size }}'
- name: Run module with backend autodetection - name: Run module with backend autodetection
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_backend_selection.csr' path: '{{ remote_tmp_dir }}/csr_backend_selection.csr'
privatekey_path: '{{ output_dir }}/privatekey_backend_selection.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey_backend_selection.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
@@ -29,12 +29,12 @@
- name: Remove output directory - name: Remove output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: absent state: absent
- name: Re-create output directory - name: Re-create output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: directory state: directory
- block: - block:

View File

@@ -1,14 +1,14 @@
--- ---
- name: "({{ select_crypto_backend }}) Validate CSR (test - privatekey modulus)" - name: "({{ select_crypto_backend }}) Validate CSR (test - privatekey modulus)"
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ output_dir }}/privatekey.pem' shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ remote_tmp_dir }}/privatekey.pem'
register: privatekey_modulus register: privatekey_modulus
- name: "({{ select_crypto_backend }}) Validate CSR (test - Common Name)" - name: "({{ select_crypto_backend }}) Validate CSR (test - Common Name)"
shell: "{{ openssl_binary }} req -noout -subject -in {{ output_dir }}/csr.csr -nameopt oneline,-space_eq" shell: "{{ openssl_binary }} req -noout -subject -in {{ remote_tmp_dir }}/csr.csr -nameopt oneline,-space_eq"
register: csr_cn register: csr_cn
- name: "({{ select_crypto_backend }}) Validate CSR (test - csr modulus)" - name: "({{ select_crypto_backend }}) Validate CSR (test - csr modulus)"
shell: '{{ openssl_binary }} req -noout -modulus -in {{ output_dir }}/csr.csr' shell: '{{ openssl_binary }} req -noout -modulus -in {{ remote_tmp_dir }}/csr.csr'
register: csr_modulus register: csr_modulus
- name: "({{ select_crypto_backend }}) Validate CSR (assert)" - name: "({{ select_crypto_backend }}) Validate CSR (assert)"
@@ -25,11 +25,16 @@
- generate_csr_idempotent is not changed - generate_csr_idempotent is not changed
- generate_csr_idempotent_check is not changed - generate_csr_idempotent_check is not changed
- name: "({{ select_crypto_backend }}) Read CSR"
slurp:
src: '{{ remote_tmp_dir }}/csr.csr'
register: slurp
- name: "({{ select_crypto_backend }}) Validate CSR (data retrieval)" - name: "({{ select_crypto_backend }}) Validate CSR (data retrieval)"
assert: assert:
that: that:
- generate_csr_check.csr is none - generate_csr_check.csr is none
- generate_csr.csr == lookup('file', output_dir ~ '/csr.csr', rstrip=False) - generate_csr.csr == (slurp.content | b64decode)
- generate_csr.csr == generate_csr_idempotent.csr - generate_csr.csr == generate_csr_idempotent.csr
- generate_csr.csr == generate_csr_idempotent_check.csr - generate_csr.csr == generate_csr_idempotent_check.csr
@@ -49,11 +54,11 @@
- csr_ku_xku_change_2 is changed - csr_ku_xku_change_2 is changed
- name: "({{ select_crypto_backend }}) Validate old_API CSR (test - Common Name)" - name: "({{ select_crypto_backend }}) Validate old_API CSR (test - Common Name)"
shell: "{{ openssl_binary }} req -noout -subject -in {{ output_dir }}/csr_oldapi.csr -nameopt oneline,-space_eq" shell: "{{ openssl_binary }} req -noout -subject -in {{ remote_tmp_dir }}/csr_oldapi.csr -nameopt oneline,-space_eq"
register: csr_oldapi_cn register: csr_oldapi_cn
- name: "({{ select_crypto_backend }}) Validate old_API CSR (test - csr modulus)" - name: "({{ select_crypto_backend }}) Validate old_API CSR (test - csr modulus)"
shell: '{{ openssl_binary }} req -noout -modulus -in {{ output_dir }}/csr_oldapi.csr' shell: '{{ openssl_binary }} req -noout -modulus -in {{ remote_tmp_dir }}/csr_oldapi.csr'
register: csr_oldapi_modulus register: csr_oldapi_modulus
- name: "({{ select_crypto_backend }}) Validate old_API CSR (assert)" - name: "({{ select_crypto_backend }}) Validate old_API CSR (assert)"
@@ -78,7 +83,7 @@
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.0', '<') when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.0', '<')
- name: "({{ select_crypto_backend }}) Validate OCSP Must Staple CSR (test - everything)" - name: "({{ select_crypto_backend }}) Validate OCSP Must Staple CSR (test - everything)"
shell: "{{ openssl_binary }} req -noout -in {{ output_dir }}/csr_ocsp.csr -text" shell: "{{ openssl_binary }} req -noout -in {{ remote_tmp_dir }}/csr_ocsp.csr -text"
register: csr_ocsp register: csr_ocsp
- name: "({{ select_crypto_backend }}) Validate OCSP Must Staple CSR (assert)" - name: "({{ select_crypto_backend }}) Validate OCSP Must Staple CSR (assert)"
@@ -93,15 +98,15 @@
- csr_ocsp_idempotency is not changed - csr_ocsp_idempotency is not changed
- name: "({{ select_crypto_backend }}) Validate ECC CSR (test - privatekey's public key)" - name: "({{ select_crypto_backend }}) Validate ECC CSR (test - privatekey's public key)"
shell: '{{ openssl_binary }} ec -pubout -in {{ output_dir }}/privatekey2.pem' shell: '{{ openssl_binary }} ec -pubout -in {{ remote_tmp_dir }}/privatekey2.pem'
register: privatekey_ecc_key register: privatekey_ecc_key
- name: "({{ select_crypto_backend }}) Validate ECC CSR (test - Common Name)" - name: "({{ select_crypto_backend }}) Validate ECC CSR (test - Common Name)"
shell: "{{ openssl_binary }} req -noout -subject -in {{ output_dir }}/csr2.csr -nameopt oneline,-space_eq" shell: "{{ openssl_binary }} req -noout -subject -in {{ remote_tmp_dir }}/csr2.csr -nameopt oneline,-space_eq"
register: csr_ecc_cn register: csr_ecc_cn
- name: "({{ select_crypto_backend }}) Validate ECC CSR (test - CSR pubkey)" - name: "({{ select_crypto_backend }}) Validate ECC CSR (test - CSR pubkey)"
shell: '{{ openssl_binary }} req -noout -pubkey -in {{ output_dir }}/csr2.csr' shell: '{{ openssl_binary }} req -noout -pubkey -in {{ remote_tmp_dir }}/csr2.csr'
register: csr_ecc_pubkey register: csr_ecc_pubkey
- name: "({{ select_crypto_backend }}) Validate ECC CSR (assert)" - name: "({{ select_crypto_backend }}) Validate ECC CSR (assert)"
@@ -111,7 +116,7 @@
- csr_ecc_pubkey.stdout == privatekey_ecc_key.stdout - csr_ecc_pubkey.stdout == privatekey_ecc_key.stdout
- name: "({{ select_crypto_backend }}) Validate CSR (text common name - Common Name)" - name: "({{ select_crypto_backend }}) Validate CSR (text common name - Common Name)"
shell: "{{ openssl_binary }} req -noout -subject -in {{ output_dir }}/csr3.csr -nameopt oneline,-space_eq" shell: "{{ openssl_binary }} req -noout -subject -in {{ remote_tmp_dir }}/csr3.csr -nameopt oneline,-space_eq"
register: csr3_cn register: csr3_cn
- name: "({{ select_crypto_backend }}) Validate CSR (assert)" - name: "({{ select_crypto_backend }}) Validate CSR (assert)"
@@ -219,16 +224,16 @@
- everything_info.subject.emailAddress == "test@example.com" - everything_info.subject.emailAddress == "test@example.com"
- everything_info.subject.givenName == "First Name" - everything_info.subject.givenName == "First Name"
- everything_info.subject.localityName == "Somewhere" - everything_info.subject.localityName == "Somewhere"
- everything_info.subject.organizationName == "Ansible" - everything_info.subject.organizationName == "Ansiblé"
- everything_info.subject.organizationalUnitName == "Crypto Department" - everything_info.subject.organizationalUnitName == "Crÿpto Depârtment"
- everything_info.subject.postalAddress == "1234 Somewhere" - everything_info.subject.postalAddress == "1234 Somewhere"
- everything_info.subject.postalCode == "1234" - everything_info.subject.postalCode == "1234"
- everything_info.subject.pseudonym == "test" - everything_info.subject.pseudonym == "test"
- everything_info.subject.serialNumber == "1234" - everything_info.subject.serialNumber == "1234"
- everything_info.subject.stateOrProvinceName == "Zurich" - everything_info.subject.stateOrProvinceName == "Zürich"
- everything_info.subject.streetAddress == "Welcome Street" - everything_info.subject.streetAddress == "Welcome Street N° 5"
- everything_info.subject.surname == "Last Name" - everything_info.subject.surname == "Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr."
- everything_info.subject.title == "Chief" - everything_info.subject.title == "Chïeff"
- everything_info.subject.userId == "asdf" - everything_info.subject.userId == "asdf"
- everything_info.subject | length == 16 - everything_info.subject | length == 16
- everything_info.subject_alt_name_critical == false - everything_info.subject_alt_name_critical == false

View File

@@ -1,2 +1,3 @@
shippable/cloud/group1
shippable/posix/group1 shippable/posix/group1
destructive destructive

View File

@@ -1,3 +1,5 @@
dependencies: dependencies:
- setup_openssl - setup_openssl
- setup_pyopenssl - setup_pyopenssl
- setup_remote_tmp_dir
- prepare_jinja2_compat

View File

@@ -4,11 +4,11 @@
- name: "({{ select_crypto_backend }}) Get CSR info" - name: "({{ select_crypto_backend }}) Get CSR info"
openssl_csr_info: openssl_csr_info:
path: '{{ output_dir }}/csr_1.csr' path: '{{ remote_tmp_dir }}/csr_1.csr'
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: result register: result
- name: "({{ select_crypto_backend }}) Check whether subject behaves as expected" - name: "({{ select_crypto_backend }}) Check whether subject and extensions behaves as expected"
assert: assert:
that: that:
- result.subject.organizationalUnitName == 'ACME Department' - result.subject.organizationalUnitName == 'ACME Department'
@@ -16,6 +16,21 @@
- "['organizationalUnitName', 'ACME Department'] in result.subject_ordered" - "['organizationalUnitName', 'ACME Department'] in result.subject_ordered"
- result.public_key_type == 'RSA' - result.public_key_type == 'RSA'
- result.public_key_data.size == default_rsa_key_size - result.public_key_data.size == default_rsa_key_size
# TLS Feature
- result.extensions_by_oid['1.3.6.1.5.5.7.1.24'].critical == false
- result.extensions_by_oid['1.3.6.1.5.5.7.1.24'].value == 'MAMCAQU='
# Key Usage
- result.extensions_by_oid['2.5.29.15'].critical == true
- result.extensions_by_oid['2.5.29.15'].value in ['AwMA/4A=', 'AwMH/4A=']
# Subject Alternative Names
- result.extensions_by_oid['2.5.29.17'].critical == false
- result.extensions_by_oid['2.5.29.17'].value == 'MGCCD3d3dy5hbnNpYmxlLmNvbYcEAQIDBIcQAAAAAAAAAAAAAAAAAAAAAYEQdGVzdEBleGFtcGxlLm9yZ4YjaHR0cHM6Ly9leGFtcGxlLm9yZy90ZXN0L2luZGV4Lmh0bWw='
# Basic Constraints
- result.extensions_by_oid['2.5.29.19'].critical == true
- result.extensions_by_oid['2.5.29.19'].value == 'MAYBAf8CARc='
# Extended Key Usage
- result.extensions_by_oid['2.5.29.37'].critical == false
- result.extensions_by_oid['2.5.29.37'].value == 'MHQGCCsGAQUFBwMBBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgGCCsGAQUFBwMJBgRVHSUABggrBgEFBQcBAwYIKwYBBQUHAwoGCCsGAQUFBwMHBggrBgEFBQcBAg=='
- name: "({{ select_crypto_backend }}) Check SubjectKeyIdentifier and AuthorityKeyIdentifier" - name: "({{ select_crypto_backend }}) Check SubjectKeyIdentifier and AuthorityKeyIdentifier"
assert: assert:
@@ -24,6 +39,10 @@
- result.authority_key_identifier == "44:55:66:77" - result.authority_key_identifier == "44:55:66:77"
- result.authority_cert_issuer == expected_authority_cert_issuer - result.authority_cert_issuer == expected_authority_cert_issuer
- result.authority_cert_serial_number == 12345 - result.authority_cert_serial_number == 12345
# Subject Key Identifier
- result.extensions_by_oid['2.5.29.14'].critical == false
# Authority Key Identifier
- result.extensions_by_oid['2.5.29.35'].critical == false
vars: vars:
expected_authority_cert_issuer: expected_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
@@ -34,9 +53,14 @@
set_fact: set_fact:
info_results: "{{ info_results + [result] }}" info_results: "{{ info_results + [result] }}"
- name: "({{ select_crypto_backend }}) Read CSR"
slurp:
src: '{{ remote_tmp_dir }}/csr_1.csr'
register: slurp
- name: "({{ select_crypto_backend }}) Get CSR info directly" - name: "({{ select_crypto_backend }}) Get CSR info directly"
openssl_csr_info: openssl_csr_info:
content: '{{ lookup("file", output_dir ~ "/csr_1.csr") }}' content: '{{ slurp.content | b64decode }}'
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: result_direct register: result_direct
@@ -47,7 +71,7 @@
- name: "({{ select_crypto_backend }}) Get CSR info" - name: "({{ select_crypto_backend }}) Get CSR info"
openssl_csr_info: openssl_csr_info:
path: '{{ output_dir }}/csr_2.csr' path: '{{ remote_tmp_dir }}/csr_2.csr'
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: result register: result
@@ -57,7 +81,7 @@
- name: "({{ select_crypto_backend }}) Get CSR info" - name: "({{ select_crypto_backend }}) Get CSR info"
openssl_csr_info: openssl_csr_info:
path: '{{ output_dir }}/csr_3.csr' path: '{{ remote_tmp_dir }}/csr_3.csr'
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: result register: result
@@ -79,7 +103,7 @@
- name: "({{ select_crypto_backend }}) Get CSR info" - name: "({{ select_crypto_backend }}) Get CSR info"
openssl_csr_info: openssl_csr_info:
path: '{{ output_dir }}/csr_4.csr' path: '{{ remote_tmp_dir }}/csr_4.csr'
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: result register: result

View File

@@ -6,12 +6,12 @@
- name: Generate privatekey - name: Generate privatekey
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/privatekey.pem' path: '{{ remote_tmp_dir }}/privatekey.pem'
size: '{{ default_rsa_key_size }}' size: '{{ default_rsa_key_size }}'
- name: Generate privatekey with password - name: Generate privatekey with password
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem' path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2 passphrase: hunter2
cipher: auto cipher: auto
select_crypto_backend: cryptography select_crypto_backend: cryptography
@@ -19,8 +19,8 @@
- name: Generate CSR 1 - name: Generate CSR 1
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_1.csr' path: '{{ remote_tmp_dir }}/csr_1.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.example.com commonName: www.example.com
C: de C: de
@@ -87,8 +87,8 @@
- name: Generate CSR 2 - name: Generate CSR 2
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_2.csr' path: '{{ remote_tmp_dir }}/csr_2.csr'
privatekey_path: '{{ output_dir }}/privatekeypw.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: hunter2 privatekey_passphrase: hunter2
useCommonNameForSAN: no useCommonNameForSAN: no
basic_constraints: basic_constraints:
@@ -96,8 +96,8 @@
- name: Generate CSR 3 - name: Generate CSR 3
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_3.csr' path: '{{ remote_tmp_dir }}/csr_3.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
useCommonNameForSAN: no useCommonNameForSAN: no
subject_alt_name: subject_alt_name:
- "DNS:*.ansible.com" - "DNS:*.ansible.com"
@@ -114,8 +114,8 @@
- name: Generate CSR 4 - name: Generate CSR 4
openssl_csr: openssl_csr:
path: '{{ output_dir }}/csr_4.csr' path: '{{ remote_tmp_dir }}/csr_4.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
useCommonNameForSAN: no useCommonNameForSAN: no
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}'

View File

@@ -1,15 +0,0 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
def compatibility_in_test(a, b):
return a in b
class TestModule:
''' Ansible math jinja2 tests '''
def tests(self):
return {
'in': compatibility_in_test,
}

View File

@@ -1,2 +1,3 @@
shippable/cloud/group1
shippable/posix/group1 shippable/posix/group1
destructive destructive

View File

@@ -1,3 +1,4 @@
dependencies: dependencies:
- setup_openssl - setup_openssl
- setup_pyopenssl - setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -1,12 +1,12 @@
--- ---
- name: "({{ select_crypto_backend }}) Generate privatekey" - name: "({{ select_crypto_backend }}) Generate privatekey"
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/privatekey.pem' path: '{{ remote_tmp_dir }}/privatekey.pem'
size: '{{ default_rsa_key_size }}' size: '{{ default_rsa_key_size }}'
- name: "({{ select_crypto_backend }}) Generate CSR (check mode)" - name: "({{ select_crypto_backend }}) Generate CSR (check mode)"
openssl_csr_pipe: openssl_csr_pipe:
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -15,7 +15,7 @@
- name: "({{ select_crypto_backend }}) Generate CSR" - name: "({{ select_crypto_backend }}) Generate CSR"
openssl_csr_pipe: openssl_csr_pipe:
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -24,7 +24,7 @@
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent)" - name: "({{ select_crypto_backend }}) Generate CSR (idempotent)"
openssl_csr_pipe: openssl_csr_pipe:
content: "{{ generate_csr.csr }}" content: "{{ generate_csr.csr }}"
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -33,7 +33,7 @@
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent, check mode)" - name: "({{ select_crypto_backend }}) Generate CSR (idempotent, check mode)"
openssl_csr_pipe: openssl_csr_pipe:
content: "{{ generate_csr.csr }}" content: "{{ generate_csr.csr }}"
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -43,7 +43,7 @@
- name: "({{ select_crypto_backend }}) Generate CSR (changed)" - name: "({{ select_crypto_backend }}) Generate CSR (changed)"
openssl_csr_pipe: openssl_csr_pipe:
content: "{{ generate_csr.csr }}" content: "{{ generate_csr.csr }}"
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: ansible.com commonName: ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -52,7 +52,7 @@
- name: "({{ select_crypto_backend }}) Generate CSR (changed, check mode)" - name: "({{ select_crypto_backend }}) Generate CSR (changed, check mode)"
openssl_csr_pipe: openssl_csr_pipe:
content: "{{ generate_csr.csr }}" content: "{{ generate_csr.csr }}"
privatekey_path: '{{ output_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject: subject:
commonName: ansible.com commonName: ansible.com
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
@@ -60,7 +60,7 @@
register: generate_csr_changed_check register: generate_csr_changed_check
- name: "({{ select_crypto_backend }}) Validate CSR (test - privatekey modulus)" - name: "({{ select_crypto_backend }}) Validate CSR (test - privatekey modulus)"
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ output_dir }}/privatekey.pem' shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ remote_tmp_dir }}/privatekey.pem'
register: privatekey_modulus register: privatekey_modulus
- name: "({{ select_crypto_backend }}) Validate CSR (test - Common Name)" - name: "({{ select_crypto_backend }}) Validate CSR (test - Common Name)"

View File

@@ -6,11 +6,11 @@
- name: Prepare private key for backend autodetection test - name: Prepare private key for backend autodetection test
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/privatekey_backend_selection.pem' path: '{{ remote_tmp_dir }}/privatekey_backend_selection.pem'
size: '{{ default_rsa_key_size }}' size: '{{ default_rsa_key_size }}'
- name: Run module with backend autodetection - name: Run module with backend autodetection
openssl_csr_pipe: openssl_csr_pipe:
privatekey_path: '{{ output_dir }}/privatekey_backend_selection.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey_backend_selection.pem'
subject: subject:
commonName: www.ansible.com commonName: www.ansible.com
@@ -24,12 +24,12 @@
- name: Remove output directory - name: Remove output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: absent state: absent
- name: Re-create output directory - name: Re-create output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: directory state: directory
- block: - block:

View File

@@ -1,2 +1,3 @@
shippable/cloud/group1
shippable/posix/group1 shippable/posix/group1
destructive destructive

View File

@@ -1,2 +1,3 @@
dependencies: dependencies:
- setup_openssl - setup_openssl
- setup_remote_tmp_dir

View File

@@ -4,7 +4,7 @@
- name: "[{{ select_crypto_backend }}] Generate parameter (check mode)" - name: "[{{ select_crypto_backend }}] Generate parameter (check mode)"
openssl_dhparam: openssl_dhparam:
size: 768 size: 768
path: '{{ output_dir }}/dh768.pem' path: '{{ remote_tmp_dir }}/dh768.pem'
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
return_content: yes return_content: yes
check_mode: true check_mode: true
@@ -13,7 +13,7 @@
- name: "[{{ select_crypto_backend }}] Generate parameter" - name: "[{{ select_crypto_backend }}] Generate parameter"
openssl_dhparam: openssl_dhparam:
size: 768 size: 768
path: '{{ output_dir }}/dh768.pem' path: '{{ remote_tmp_dir }}/dh768.pem'
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
return_content: yes return_content: yes
register: dhparam register: dhparam
@@ -21,7 +21,7 @@
- name: "[{{ select_crypto_backend }}] Don't regenerate parameters with no change (check mode)" - name: "[{{ select_crypto_backend }}] Don't regenerate parameters with no change (check mode)"
openssl_dhparam: openssl_dhparam:
size: 768 size: 768
path: '{{ output_dir }}/dh768.pem' path: '{{ remote_tmp_dir }}/dh768.pem'
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
return_content: yes return_content: yes
check_mode: true check_mode: true
@@ -30,39 +30,39 @@
- name: "[{{ select_crypto_backend }}] Don't regenerate parameters with no change" - name: "[{{ select_crypto_backend }}] Don't regenerate parameters with no change"
openssl_dhparam: openssl_dhparam:
size: 768 size: 768
path: '{{ output_dir }}/dh768.pem' path: '{{ remote_tmp_dir }}/dh768.pem'
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
return_content: yes return_content: yes
register: dhparam_changed register: dhparam_changed
- name: "[{{ select_crypto_backend }}] Generate parameters with size option" - name: "[{{ select_crypto_backend }}] Generate parameters with size option"
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dh512.pem' path: '{{ remote_tmp_dir }}/dh512.pem'
size: 512 size: 512
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
- name: "[{{ select_crypto_backend }}] Don't regenerate parameters with size option and no change" - name: "[{{ select_crypto_backend }}] Don't regenerate parameters with size option and no change"
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dh512.pem' path: '{{ remote_tmp_dir }}/dh512.pem'
size: 512 size: 512
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
register: dhparam_changed_512 register: dhparam_changed_512
- copy: - copy:
src: '{{ output_dir }}/dh768.pem' src: '{{ remote_tmp_dir }}/dh768.pem'
remote_src: yes remote_src: yes
dest: '{{ output_dir }}/dh512.pem' dest: '{{ remote_tmp_dir }}/dh512.pem'
- name: "[{{ select_crypto_backend }}] Re-generate if size is different" - name: "[{{ select_crypto_backend }}] Re-generate if size is different"
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dh512.pem' path: '{{ remote_tmp_dir }}/dh512.pem'
size: 512 size: 512
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
register: dhparam_changed_to_512 register: dhparam_changed_to_512
- name: "[{{ select_crypto_backend }}] Force re-generate parameters with size option" - name: "[{{ select_crypto_backend }}] Force re-generate parameters with size option"
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dh512.pem' path: '{{ remote_tmp_dir }}/dh512.pem'
size: 512 size: 512
force: yes force: yes
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
@@ -70,11 +70,11 @@
- name: "[{{ select_crypto_backend }}] Create broken params" - name: "[{{ select_crypto_backend }}] Create broken params"
copy: copy:
dest: "{{ output_dir }}/dhbroken.pem" dest: "{{ remote_tmp_dir }}/dhbroken.pem"
content: "broken" content: "broken"
- name: "[{{ select_crypto_backend }}] Regenerate broken params" - name: "[{{ select_crypto_backend }}] Regenerate broken params"
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dhbroken.pem' path: '{{ remote_tmp_dir }}/dhbroken.pem'
size: 512 size: 512
force: yes force: yes
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
@@ -82,21 +82,21 @@
- name: "[{{ select_crypto_backend }}] Generate params" - name: "[{{ select_crypto_backend }}] Generate params"
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dh_backup.pem' path: '{{ remote_tmp_dir }}/dh_backup.pem'
size: 512 size: 512
backup: yes backup: yes
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
register: dhparam_backup_1 register: dhparam_backup_1
- name: "[{{ select_crypto_backend }}] Generate params (idempotent)" - name: "[{{ select_crypto_backend }}] Generate params (idempotent)"
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dh_backup.pem' path: '{{ remote_tmp_dir }}/dh_backup.pem'
size: 512 size: 512
backup: yes backup: yes
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
register: dhparam_backup_2 register: dhparam_backup_2
- name: "[{{ select_crypto_backend }}] Generate params (change)" - name: "[{{ select_crypto_backend }}] Generate params (change)"
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dh_backup.pem' path: '{{ remote_tmp_dir }}/dh_backup.pem'
size: 512 size: 512
force: yes force: yes
backup: yes backup: yes
@@ -104,7 +104,7 @@
register: dhparam_backup_3 register: dhparam_backup_3
- name: "[{{ select_crypto_backend }}] Generate params (remove)" - name: "[{{ select_crypto_backend }}] Generate params (remove)"
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dh_backup.pem' path: '{{ remote_tmp_dir }}/dh_backup.pem'
state: absent state: absent
backup: yes backup: yes
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"
@@ -112,7 +112,7 @@
register: dhparam_backup_4 register: dhparam_backup_4
- name: "[{{ select_crypto_backend }}] Generate params (remove, idempotent)" - name: "[{{ select_crypto_backend }}] Generate params (remove, idempotent)"
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dh_backup.pem' path: '{{ remote_tmp_dir }}/dh_backup.pem'
state: absent state: absent
backup: yes backup: yes
select_crypto_backend: "{{ select_crypto_backend }}" select_crypto_backend: "{{ select_crypto_backend }}"

View File

@@ -9,7 +9,7 @@
- name: Run module with backend autodetection - name: Run module with backend autodetection
openssl_dhparam: openssl_dhparam:
path: '{{ output_dir }}/dh_backend_selection.pem' path: '{{ remote_tmp_dir }}/dh_backend_selection.pem'
size: 512 size: 512
- block: - block:
@@ -24,12 +24,12 @@
- name: Remove output directory - name: Remove output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: absent state: absent
- name: Re-create output directory - name: Re-create output directory
file: file:
path: "{{ output_dir }}" path: "{{ remote_tmp_dir }}"
state: directory state: directory
- block: - block:

View File

@@ -1,12 +1,12 @@
--- ---
- name: "[{{ select_crypto_backend }}] Validate generated params" - name: "[{{ select_crypto_backend }}] Validate generated params"
shell: '{{ openssl_binary }} dhparam -in {{ output_dir }}/{{ item }}.pem -noout -check' shell: '{{ openssl_binary }} dhparam -in {{ remote_tmp_dir }}/{{ item }}.pem -noout -check'
with_items: with_items:
- dh768 - dh768
- dh512 - dh512
- name: "[{{ select_crypto_backend }}] Get bit size of 768" - name: "[{{ select_crypto_backend }}] Get bit size of 768"
shell: '{{ openssl_binary }} dhparam -noout -in {{ output_dir }}/dh768.pem -text | head -n1 | sed -ne "s@.*(\\([[:digit:]]\{1,\}\\) bit).*@\\1@p"' shell: '{{ openssl_binary }} dhparam -noout -in {{ remote_tmp_dir }}/dh768.pem -text | head -n1 | sed -ne "s@.*(\\([[:digit:]]\{1,\}\\) bit).*@\\1@p"'
register: bit_size_dhparam register: bit_size_dhparam
- name: "[{{ select_crypto_backend }}] Check bit size of default" - name: "[{{ select_crypto_backend }}] Check bit size of default"
@@ -15,7 +15,7 @@
- bit_size_dhparam.stdout == "768" - bit_size_dhparam.stdout == "768"
- name: "[{{ select_crypto_backend }}] Get bit size of 512" - name: "[{{ select_crypto_backend }}] Get bit size of 512"
shell: '{{ openssl_binary }} dhparam -noout -in {{ output_dir }}/dh512.pem -text | head -n1 | sed -ne "s@.*(\\([[:digit:]]\{1,\}\\) bit).*@\\1@p"' shell: '{{ openssl_binary }} dhparam -noout -in {{ remote_tmp_dir }}/dh512.pem -text | head -n1 | sed -ne "s@.*(\\([[:digit:]]\{1,\}\\) bit).*@\\1@p"'
register: bit_size_dhparam_512 register: bit_size_dhparam_512
- name: "[{{ select_crypto_backend }}] Check bit size of default" - name: "[{{ select_crypto_backend }}] Check bit size of default"
@@ -34,10 +34,15 @@
- dhparam_changed_to_512 is changed - dhparam_changed_to_512 is changed
- dhparam_changed_force is changed - dhparam_changed_force is changed
- name: "[{{ select_crypto_backend }}] Read result"
slurp:
src: '{{ remote_tmp_dir }}/dh768.pem'
register: slurp
- name: "[{{ select_crypto_backend }}] Make sure correct values are returned" - name: "[{{ select_crypto_backend }}] Make sure correct values are returned"
assert: assert:
that: that:
- dhparam.dhparams == lookup('file', output_dir ~ '/dh768.pem', rstrip=False) - dhparam.dhparams == (slurp.content | b64decode)
- dhparam.dhparams == dhparam_changed.dhparams - dhparam.dhparams == dhparam_changed.dhparams
- name: "[{{ select_crypto_backend }}] Verify that broken params will be regenerated" - name: "[{{ select_crypto_backend }}] Verify that broken params will be regenerated"

View File

@@ -1,2 +1,3 @@
shippable/cloud/group1
shippable/posix/group1 shippable/posix/group1
destructive destructive

View File

@@ -1,3 +1,4 @@
dependencies: dependencies:
- setup_openssl - setup_openssl
- setup_pyopenssl - setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -2,10 +2,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (check mode)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file (check mode)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12' path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
return_content: true return_content: true
check_mode: true check_mode: true
@@ -14,10 +14,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12' path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
return_content: true return_content: true
register: p12_standard register: p12_standard
@@ -25,10 +25,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file again, idempotency (check mode)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file again, idempotency (check mode)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12' path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
return_content: true return_content: true
check_mode: true check_mode: true
@@ -37,17 +37,17 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file again, idempotency" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file again, idempotency"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12' path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
return_content: true return_content: true
register: p12_standard_idempotency register: p12_standard_idempotency
- name: "({{ select_crypto_backend }}) Read ansible.p12" - name: "({{ select_crypto_backend }}) Read ansible.p12"
slurp: slurp:
src: '{{ output_dir }}/ansible.p12' src: '{{ remote_tmp_dir }}/ansible.p12'
register: ansible_p12_content register: ansible_p12_content
- name: "({{ select_crypto_backend }}) Validate PKCS#12" - name: "({{ select_crypto_backend }}) Validate PKCS#12"
@@ -59,10 +59,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (force)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file (force)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12' path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
force: true force: true
register: p12_force register: p12_force
@@ -70,10 +70,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (force + change mode)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file (force + change mode)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12' path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
force: true force: true
mode: '0644' mode: '0644'
@@ -82,8 +82,8 @@
- name: "({{ select_crypto_backend }}) Dump PKCS#12" - name: "({{ select_crypto_backend }}) Dump PKCS#12"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
src: '{{ output_dir }}/ansible.p12' src: '{{ remote_tmp_dir }}/ansible.p12'
path: '{{ output_dir }}/ansible_parse.pem' path: '{{ remote_tmp_dir }}/ansible_parse.pem'
action: parse action: parse
state: present state: present
register: p12_dumped register: p12_dumped
@@ -91,8 +91,8 @@
- name: "({{ select_crypto_backend }}) Dump PKCS#12 file again, idempotency" - name: "({{ select_crypto_backend }}) Dump PKCS#12 file again, idempotency"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
src: '{{ output_dir }}/ansible.p12' src: '{{ remote_tmp_dir }}/ansible.p12'
path: '{{ output_dir }}/ansible_parse.pem' path: '{{ remote_tmp_dir }}/ansible_parse.pem'
action: parse action: parse
state: present state: present
register: p12_dumped_idempotency register: p12_dumped_idempotency
@@ -100,8 +100,8 @@
- name: "({{ select_crypto_backend }}) Dump PKCS#12, check mode" - name: "({{ select_crypto_backend }}) Dump PKCS#12, check mode"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
src: '{{ output_dir }}/ansible.p12' src: '{{ remote_tmp_dir }}/ansible.p12'
path: '{{ output_dir }}/ansible_parse.pem' path: '{{ remote_tmp_dir }}/ansible_parse.pem'
action: parse action: parse
state: present state: present
check_mode: true check_mode: true
@@ -110,36 +110,36 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file with multiple certs and passphrase" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file with multiple certs and passphrase"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_multi_certs.p12' path: '{{ remote_tmp_dir }}/ansible_multi_certs.p12'
friendly_name: abracadabra friendly_name: abracadabra
passphrase: hunter3 passphrase: hunter3
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
other_certificates: other_certificates:
- '{{ output_dir }}/ansible2.crt' - '{{ remote_tmp_dir }}/ansible2.crt'
- '{{ output_dir }}/ansible3.crt' - '{{ remote_tmp_dir }}/ansible3.crt'
state: present state: present
register: p12_multiple_certs register: p12_multiple_certs
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file with multiple certs and passphrase, again (idempotency)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file with multiple certs and passphrase, again (idempotency)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_multi_certs.p12' path: '{{ remote_tmp_dir }}/ansible_multi_certs.p12'
friendly_name: abracadabra friendly_name: abracadabra
passphrase: hunter3 passphrase: hunter3
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
other_certificates: other_certificates:
- '{{ output_dir }}/ansible2.crt' - '{{ remote_tmp_dir }}/ansible2.crt'
- '{{ output_dir }}/ansible3.crt' - '{{ remote_tmp_dir }}/ansible3.crt'
state: present state: present
register: p12_multiple_certs_idempotency register: p12_multiple_certs_idempotency
- name: "({{ select_crypto_backend }}) Dump PKCS#12 with multiple certs and passphrase" - name: "({{ select_crypto_backend }}) Dump PKCS#12 with multiple certs and passphrase"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
src: '{{ output_dir }}/ansible_multi_certs.p12' src: '{{ remote_tmp_dir }}/ansible_multi_certs.p12'
path: '{{ output_dir }}/ansible_parse_multi_certs.pem' path: '{{ remote_tmp_dir }}/ansible_parse_multi_certs.pem'
passphrase: hunter3 passphrase: hunter3
action: parse action: parse
state: present state: present
@@ -147,11 +147,11 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (password fail 1)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file (password fail 1)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_pw1.p12' path: '{{ remote_tmp_dir }}/ansible_pw1.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
privatekey_passphrase: hunter2 privatekey_passphrase: hunter2
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
ignore_errors: true ignore_errors: true
register: passphrase_error_1 register: passphrase_error_1
@@ -159,11 +159,11 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (password fail 2)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file (password fail 2)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_pw2.p12' path: '{{ remote_tmp_dir }}/ansible_pw2.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/privatekeypw.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: wrong_password privatekey_passphrase: wrong_password
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
ignore_errors: true ignore_errors: true
register: passphrase_error_2 register: passphrase_error_2
@@ -171,10 +171,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (password fail 3)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file (password fail 3)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_pw3.p12' path: '{{ remote_tmp_dir }}/ansible_pw3.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/privatekeypw.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
ignore_errors: true ignore_errors: true
register: passphrase_error_3 register: passphrase_error_3
@@ -182,24 +182,24 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file, no privatekey" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file, no privatekey"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_no_pkey.p12' path: '{{ remote_tmp_dir }}/ansible_no_pkey.p12'
friendly_name: abracadabra friendly_name: abracadabra
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
register: p12_no_pkey register: p12_no_pkey
- name: "({{ select_crypto_backend }}) Create broken PKCS#12" - name: "({{ select_crypto_backend }}) Create broken PKCS#12"
copy: copy:
dest: '{{ output_dir }}/broken.p12' dest: '{{ remote_tmp_dir }}/broken.p12'
content: broken content: broken
- name: "({{ select_crypto_backend }}) Regenerate broken PKCS#12" - name: "({{ select_crypto_backend }}) Regenerate broken PKCS#12"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/broken.p12' path: '{{ remote_tmp_dir }}/broken.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
force: true force: true
mode: '0644' mode: '0644'
@@ -208,10 +208,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_backup.p12' path: '{{ remote_tmp_dir }}/ansible_backup.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
backup: true backup: true
register: p12_backup_1 register: p12_backup_1
@@ -219,10 +219,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (idempotent)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file (idempotent)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_backup.p12' path: '{{ remote_tmp_dir }}/ansible_backup.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
backup: true backup: true
register: p12_backup_2 register: p12_backup_2
@@ -230,10 +230,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (change)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file (change)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_backup.p12' path: '{{ remote_tmp_dir }}/ansible_backup.p12'
friendly_name: abra friendly_name: abra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
force: true force: true
backup: true backup: true
@@ -242,7 +242,7 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (remove)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file (remove)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_backup.p12' path: '{{ remote_tmp_dir }}/ansible_backup.p12'
state: absent state: absent
backup: true backup: true
return_content: true return_content: true
@@ -251,7 +251,7 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (remove, idempotent)" - name: "({{ select_crypto_backend }}) Generate PKCS#12 file (remove, idempotent)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_backup.p12' path: '{{ remote_tmp_dir }}/ansible_backup.p12'
state: absent state: absent
backup: true backup: true
register: p12_backup_5 register: p12_backup_5
@@ -259,11 +259,11 @@
- name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file" - name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_empty.p12' path: '{{ remote_tmp_dir }}/ansible_empty.p12'
friendly_name: abracadabra friendly_name: abracadabra
other_certificates: other_certificates:
- '{{ output_dir }}/ansible2.crt' - '{{ remote_tmp_dir }}/ansible2.crt'
- '{{ output_dir }}/ansible3.crt' - '{{ remote_tmp_dir }}/ansible3.crt'
state: present state: present
register: p12_empty register: p12_empty
@@ -271,21 +271,21 @@
- name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file (idempotent)" - name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file (idempotent)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_empty.p12' path: '{{ remote_tmp_dir }}/ansible_empty.p12'
friendly_name: abracadabra friendly_name: abracadabra
other_certificates: other_certificates:
- '{{ output_dir }}/ansible3.crt' - '{{ remote_tmp_dir }}/ansible3.crt'
- '{{ output_dir }}/ansible2.crt' - '{{ remote_tmp_dir }}/ansible2.crt'
state: present state: present
register: p12_empty_idem register: p12_empty_idem
- name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file (idempotent, concatenated other certificates)" - name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file (idempotent, concatenated other certificates)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_empty.p12' path: '{{ remote_tmp_dir }}/ansible_empty.p12'
friendly_name: abracadabra friendly_name: abracadabra
other_certificates: other_certificates:
- '{{ output_dir }}/ansible23.crt' - '{{ remote_tmp_dir }}/ansible23.crt'
other_certificates_parse_all: true other_certificates_parse_all: true
state: present state: present
register: p12_empty_concat_idem register: p12_empty_concat_idem
@@ -293,8 +293,8 @@
- name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file (parse)" - name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file (parse)"
openssl_pkcs12: openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
src: '{{ output_dir }}/ansible_empty.p12' src: '{{ remote_tmp_dir }}/ansible_empty.p12'
path: '{{ output_dir }}/ansible_empty.pem' path: '{{ remote_tmp_dir }}/ansible_empty.pem'
action: parse action: parse
- import_tasks: ../tests/validate.yml - import_tasks: ../tests/validate.yml
@@ -303,7 +303,7 @@
- name: "({{ select_crypto_backend }}) Delete PKCS#12 file" - name: "({{ select_crypto_backend }}) Delete PKCS#12 file"
openssl_pkcs12: openssl_pkcs12:
state: absent state: absent
path: '{{ output_dir }}/{{ item }}.p12' path: '{{ remote_tmp_dir }}/{{ item }}.p12'
loop: loop:
- ansible - ansible
- ansible_no_pkey - ansible_no_pkey

View File

@@ -7,50 +7,56 @@
- block: - block:
- name: Generate private keys - name: Generate private keys
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/ansible_pkey{{ item }}.pem' path: '{{ remote_tmp_dir }}/ansible_pkey{{ item }}.pem'
size: '{{ default_rsa_key_size_certifiates }}' size: '{{ default_rsa_key_size_certifiates }}'
loop: "{{ range(1, 4) | list }}" loop: "{{ range(1, 4) | list }}"
- name: Generate privatekey with password - name: Generate privatekey with password
openssl_privatekey: openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem' path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2 passphrase: hunter2
cipher: auto cipher: auto
size: '{{ default_rsa_key_size }}' size: '{{ default_rsa_key_size }}'
- name: Generate CSRs - name: Generate CSRs
openssl_csr: openssl_csr:
path: '{{ output_dir }}/ansible{{ item }}.csr' path: '{{ remote_tmp_dir }}/ansible{{ item }}.csr'
privatekey_path: '{{ output_dir }}/ansible_pkey{{ item }}.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey{{ item }}.pem'
commonName: www{{ item }}.ansible.com commonName: www{{ item }}.ansible.com
loop: "{{ range(1, 4) | list }}" loop: "{{ range(1, 4) | list }}"
- name: Generate certificate - name: Generate certificate
x509_certificate: x509_certificate:
path: '{{ output_dir }}/ansible{{ item }}.crt' path: '{{ remote_tmp_dir }}/ansible{{ item }}.crt'
privatekey_path: '{{ output_dir }}/ansible_pkey{{ item }}.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey{{ item }}.pem'
csr_path: '{{ output_dir }}/ansible{{ item }}.csr' csr_path: '{{ remote_tmp_dir }}/ansible{{ item }}.csr'
provider: selfsigned provider: selfsigned
loop: "{{ range(1, 4) | list }}" loop: "{{ range(1, 4) | list }}"
- name: Read files
slurp:
src: '{{ item }}'
loop:
- "{{ remote_tmp_dir ~ '/ansible2.crt' }}"
- "{{ remote_tmp_dir ~ '/ansible3.crt' }}"
register: slurp
- name: Generate concatenated PEM file - name: Generate concatenated PEM file
copy: copy:
dest: '{{ output_dir }}/ansible23.crt' dest: '{{ remote_tmp_dir }}/ansible23.crt'
content: | content: '{{ slurp.results[0].content | b64decode }}{{ slurp.results[1].content | b64decode }}'
{{ lookup("file", output_dir ~ "/ansible2.crt") }}
{{ lookup("file", output_dir ~ "/ansible3.crt") }}
- name: Generate PKCS#12 file with backend autodetection - name: Generate PKCS#12 file with backend autodetection
openssl_pkcs12: openssl_pkcs12:
path: '{{ output_dir }}/ansible.p12' path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem' privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt' certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present state: present
- name: Delete result - name: Delete result
file: file:
path: '{{ output_dir }}/ansible.p12' path: '{{ remote_tmp_dir }}/ansible.p12'
state: absent state: absent
- block: - block:

Some files were not shown because too many files have changed in this diff Show More