Add openssl_csr_info ilter. (#554)

This commit is contained in:
Felix Fontein
2022-12-31 07:58:37 +01:00
committed by GitHub
parent 889cfdf47e
commit ef2bb6d510
6 changed files with 612 additions and 2 deletions

View File

@@ -0,0 +1,7 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
azp/generic/2
azp/posix/2
destructive

View File

@@ -0,0 +1,9 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
dependencies:
- setup_openssl
- setup_remote_tmp_dir
- prepare_jinja2_compat

View File

@@ -0,0 +1,144 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: "Get CSR info"
set_fact:
result: >-
{{ lookup('file', remote_tmp_dir ~ '/csr_1.csr') | community.crypto.openssl_csr_info }}
result_idna: >-
{{ lookup('file', remote_tmp_dir ~ '/csr_1.csr') | community.crypto.openssl_csr_info(name_encoding='idna') }}
result_unicode: >-
{{ lookup('file', remote_tmp_dir ~ '/csr_1.csr') | community.crypto.openssl_csr_info(name_encoding='unicode') }}
- name: "Check whether subject and extensions behaves as expected"
assert:
that:
- result.subject.organizationalUnitName == 'ACME Department'
- "['organizationalUnitName', 'Crypto Department'] in result.subject_ordered"
- "['organizationalUnitName', 'ACME Department'] in result.subject_ordered"
- result.public_key_type == 'RSA'
- 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.subject_alt_name[1] == ("DNS:âņsïbłè.com" if cryptography_version.stdout is version('2.1', '<') else "DNS:xn--sb-oia0a7a53bya.com")
- result_unicode.subject_alt_name[1] == "DNS:âņsïbłè.com"
- result_idna.subject_alt_name[1] == "DNS:xn--sb-oia0a7a53bya.com"
- result.extensions_by_oid['2.5.29.17'].critical == false
- result.extensions_by_oid['2.5.29.17'].value == 'MHmCD3d3dy5hbnNpYmxlLmNvbYIXeG4tLXNiLW9pYTBhN2E1M2J5YS5jb22HBAECAwSHEAAAAAAAAAAAAAAAAAAAAAGBEHRlc3RAZXhhbXBsZS5vcmeGI2h0dHBzOi8vZXhhbXBsZS5vcmcvdGVzdC9pbmRleC5odG1s'
# 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: "Check SubjectKeyIdentifier and AuthorityKeyIdentifier"
assert:
that:
- result.subject_key_identifier == "00:11:22:33"
- result.authority_key_identifier == "44:55:66:77"
- result.authority_cert_issuer == expected_authority_cert_issuer
- 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:
expected_authority_cert_issuer:
- "DNS:ca.example.org"
- "IP:1.2.3.4"
when: cryptography_version.stdout is version('1.3', '>=')
- name: "Get CSR info"
set_fact:
result: >-
{{ lookup('file', remote_tmp_dir ~ '/csr_2.csr') | community.crypto.openssl_csr_info }}
- name: "Get CSR info"
set_fact:
result: >-
{{ lookup('file', remote_tmp_dir ~ '/csr_3.csr') | community.crypto.openssl_csr_info }}
- name: "Check AuthorityKeyIdentifier"
assert:
that:
- result.authority_key_identifier is none
- result.authority_cert_issuer == expected_authority_cert_issuer
- result.authority_cert_serial_number == 12345
vars:
expected_authority_cert_issuer:
- "DNS:ca.example.org"
- "IP:1.2.3.4"
when: cryptography_version.stdout is version('1.3', '>=')
- name: "Get CSR info"
set_fact:
result: >-
{{ lookup('file', remote_tmp_dir ~ '/csr_4.csr') | community.crypto.openssl_csr_info }}
- name: "Check AuthorityKeyIdentifier"
assert:
that:
- result.authority_key_identifier == "44:55:66:77"
- result.authority_cert_issuer is none
- result.authority_cert_serial_number is none
when: cryptography_version.stdout is version('1.3', '>=')
- name: Get invalid certificate info
set_fact:
result: >-
{{ [] | community.crypto.openssl_csr_info }}
ignore_errors: true
register: output
- name: Check that task failed and error message is OK
assert:
that:
- output is failed
- output.msg is search("^The community.crypto.openssl_csr_info input must be a text type, not <(?:class|type) 'list'>$")
- name: Get invalid certificate info
set_fact:
result: >-
{{ 'foo' | community.crypto.openssl_csr_info }}
ignore_errors: true
register: output
- name: Check that task failed and error message is OK
assert:
that:
- output is failed
- output.msg is search("^Unable to load (?:request|PEM file)(?:\.|$)")
- name: Get invalid certificate info
set_fact:
result: >-
{{ 'foo' | community.crypto.openssl_csr_info(name_encoding=[]) }}
ignore_errors: true
register: output
- name: Check that task failed and error message is OK
assert:
that:
- output is failed
- output.msg is search("^The name_encoding option must be of a text type, not <(?:class|type) 'list'>$")
- name: Get invalid name_encoding parameter
set_fact:
result: >-
{{ 'bar' | community.crypto.openssl_csr_info(name_encoding='foo') }}
ignore_errors: true
register: output
- name: Check that task failed and error message is OK
assert:
that:
- output is failed
- output.msg is search("^The name_encoding option must be one of the values \"ignore\", \"idna\", or \"unicode\", not \"foo\"$")

View File

@@ -0,0 +1,133 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
####################################################################
# WARNING: These are designed specifically for Ansible tests #
# and should not be used as examples of how to write Ansible roles #
####################################################################
- name: Make sure the Python idna library is installed
pip:
name: idna
state: present
- name: Generate privatekey
openssl_privatekey:
path: '{{ remote_tmp_dir }}/privatekey.pem'
size: '{{ default_rsa_key_size }}'
- name: Generate privatekey with password
openssl_privatekey:
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: auto
size: '{{ default_rsa_key_size }}'
- name: Generate CSR 1
openssl_csr:
path: '{{ remote_tmp_dir }}/csr_1.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.example.com
C: de
L: Somewhere
ST: Zurich
streetAddress: Welcome Street
O: Ansible
organizationalUnitName:
- Crypto Department
- ACME Department
serialNumber: "1234"
SN: Last Name
GN: First Name
title: Chief
pseudonym: test
UID: asdf
emailAddress: test@example.com
postalAddress: 1234 Somewhere
postalCode: "1234"
useCommonNameForSAN: no
key_usage:
- digitalSignature
- keyAgreement
- Non Repudiation
- Key Encipherment
- dataEncipherment
- Certificate Sign
- cRLSign
- Encipher Only
- decipherOnly
key_usage_critical: yes
extended_key_usage:
- serverAuth # the same as "TLS Web Server Authentication"
- TLS Web Server Authentication
- TLS Web Client Authentication
- Code Signing
- E-mail Protection
- timeStamping
- OCSPSigning
- Any Extended Key Usage
- qcStatements
- DVCS
- IPSec User
- biometricInfo
subject_alt_name:
- "DNS:www.ansible.com"
- "DNS:âņsïbłè.com"
- "IP:1.2.3.4"
- "IP:::1"
- "email:test@example.org"
- "URI:https://example.org/test/index.html"
basic_constraints:
- "CA:TRUE"
- "pathlen:23"
basic_constraints_critical: yes
ocsp_must_staple: yes
subject_key_identifier: '{{ "00:11:22:33" 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 }}'
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}'
vars:
value_for_authority_cert_issuer:
- "DNS:ca.example.org"
- "IP:1.2.3.4"
- name: Generate CSR 2
openssl_csr:
path: '{{ remote_tmp_dir }}/csr_2.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: hunter2
useCommonNameForSAN: no
basic_constraints:
- "CA:TRUE"
- name: Generate CSR 3
openssl_csr:
path: '{{ remote_tmp_dir }}/csr_3.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
useCommonNameForSAN: no
subject_alt_name:
- "DNS:*.ansible.com"
- "DNS:*.example.org"
- "IP:DEAD:BEEF::1"
basic_constraints:
- "CA:FALSE"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}'
vars:
value_for_authority_cert_issuer:
- "DNS:ca.example.org"
- "IP:1.2.3.4"
- name: Generate CSR 4
openssl_csr:
path: '{{ remote_tmp_dir }}/csr_4.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
useCommonNameForSAN: no
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}'
- name: Running tests
include_tasks: impl.yml
when: cryptography_version.stdout is version('1.3', '>=')