Files
patchback[bot] b8d97afce1 acme_certificate tests: fix tests for listing orders (#992) (#993)
* All orders created with the ec384 account have deactivated authz.

According to the spec, these orders are invalid and should not be
listed when listing orders. With the latest Pebble version, which
handles this correctly, this causes the current tests to fail,
since they expect orders to be present.

* Orders cannot be deactivated, they are invalid.

* Make compatible with newest Pebble.

(cherry picked from commit 670d0b4dcf)

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-03-27 23:23:28 +01:00

519 lines
20 KiB
YAML

---
# 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
## SET UP ACCOUNT KEYS ########################################################################
- block:
- name: Generate account keys
community.crypto.openssl_privatekey:
path: "{{ remote_tmp_dir }}/{{ item.name }}.pem"
type: "{{ item.type }}"
size: "{{ item.size | default(omit) }}"
curve: "{{ item.curve | default(omit) }}"
force: true
loop: "{{ account_keys }}"
vars:
account_keys:
- name: account-ec256
type: ECC
curve: secp256r1
- name: account-ec384
type: ECC
curve: secp384r1
- name: account-rsa
type: RSA
size: "{{ default_rsa_key_size }}"
## SET UP ACCOUNTS ############################################################################
- name: Make sure ECC256 account hasn't been created yet
community.crypto.acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
acme_version: 2
acme_directory: "{{ acme_directory_url }}"
validate_certs: false
account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
state: absent
- name: Read account key (EC384)
ansible.builtin.slurp:
src: '{{ remote_tmp_dir }}/account-ec384.pem'
register: slurp
- name: Create ECC384 account
community.crypto.acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
acme_version: 2
acme_directory: "{{ acme_directory_url }}"
validate_certs: false
account_key_content: "{{ slurp.content | b64decode }}"
state: present
allow_creation: true
terms_agreed: true
contact:
- mailto:example@example.org
- mailto:example@example.com
- name: Create RSA account
community.crypto.acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
acme_version: 2
acme_directory: "{{ acme_directory_url }}"
validate_certs: false
account_key_src: "{{ remote_tmp_dir }}/account-rsa.pem"
state: present
allow_creation: true
terms_agreed: true
contact: []
## OBTAIN CERTIFICATES ########################################################################
- name: Obtain cert 1
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 1
certificate_name: cert-1
key_type: rsa
rsa_bits: "{{ default_rsa_key_size }}"
subject_alt_name: "DNS:example.com"
subject_alt_name_critical: false
account_key: account-ec256
challenge: http-01
modify_account: true
deactivate_authzs: false
force: false
remaining_days: 1
terms_agreed: true
account_email: "example@example.org"
retrieve_all_alternates: true
acme_expected_root_number: 1
select_chain:
- test_certificates: last
issuer: "{{ acme_roots[1].subject }}"
use_csr_content: true
- name: Store obtain results for cert 1
ansible.builtin.set_fact:
cert_1_obtain_results: "{{ certificate_obtain_result }}"
cert_1_alternate: "{{ 1 if select_crypto_backend == 'cryptography' else 0 }}"
- name: Obtain cert 2
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 2
certificate_name: cert-2
certificate_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else '' }}"
key_type: ec256
subject_alt_name: "DNS:*.example.com,DNS:example.com"
subject_alt_name_critical: true
account_key: account-ec384
challenge: dns-01
modify_account: false
deactivate_authzs: true
force: false
remaining_days: 1
terms_agreed: false
account_email: ""
acme_expected_root_number: 0
retrieve_all_alternates: true
select_chain:
# All intermediates have the same subject, so always the first
# chain will be found, and we need a second condition to make sure
# that the first condition actually works. (The second condition
# has been tested above.)
- test_certificates: all
subject: "{{ acme_intermediates[0].subject }}"
- test_certificates: all
issuer: "{{ acme_roots[2].subject }}"
use_csr_content: false
- name: Store obtain results for cert 2
ansible.builtin.set_fact:
cert_2_obtain_results: "{{ certificate_obtain_result }}"
cert_2_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}"
- name: Read account key (RSA)
ansible.builtin.slurp:
src: '{{ remote_tmp_dir }}/account-rsa.pem'
register: slurp_account_key
- name: Obtain cert 3
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 3
certificate_name: cert-3
key_type: ec384
subject_alt_name: "DNS:*.example.com,DNS:example.org,DNS:t1.example.com"
subject_alt_name_critical: false
account_key_content: "{{ slurp_account_key.content | b64decode }}"
challenge: dns-01
modify_account: false
deactivate_authzs: true
force: false
remaining_days: 1
terms_agreed: false
account_email: ""
acme_expected_root_number: 0
retrieve_all_alternates: true
select_chain:
- test_certificates: last
subject: "{{ acme_roots[1].subject }}"
use_csr_content: true
- name: Store obtain results for cert 3
ansible.builtin.set_fact:
cert_3_obtain_results: "{{ certificate_obtain_result }}"
cert_3_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}"
- name: Obtain cert 4
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 4
certificate_name: cert-4
key_type: rsa
rsa_bits: "{{ default_rsa_key_size }}"
subject_alt_name: "DNS:example.com,DNS:t1.example.com,DNS:test.t2.example.com,DNS:example.org,DNS:TesT.example.org"
subject_alt_name_critical: false
account_key: account-rsa
challenge: http-01
modify_account: false
deactivate_authzs: false
force: true
remaining_days: 1
terms_agreed: false
account_email: ""
acme_certificate_profile: "{{ 'default' if acme_supports_profiles else omit }}"
acme_expected_root_number: 2
select_chain:
- test_certificates: last
issuer: "{{ acme_roots[2].subject }}"
- test_certificates: last
issuer: "{{ acme_roots[1].subject }}"
use_csr_content: false
- name: Store obtain results for cert 4
ansible.builtin.set_fact:
cert_4_obtain_results: "{{ certificate_obtain_result }}"
cert_4_alternate: "{{ 2 if select_crypto_backend == 'cryptography' else 0 }}"
- name: Obtain cert 5
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 5, Iteration 1/4
certificate_name: cert-5
key_type: ec521
subject_alt_name: "DNS:t2.example.com"
subject_alt_name_critical: false
account_key: account-ec384
challenge: http-01
modify_account: false
deactivate_authzs: true
force: true
remaining_days: 1
terms_agreed: false
account_email: ""
use_csr_content: true
- name: Store obtain results for cert 5a
ansible.builtin.set_fact:
cert_5a_obtain_results: "{{ certificate_obtain_result }}"
cert_5_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}"
- name: Obtain cert 5 (should not, since already there and valid for more than 1 days)
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 5, Iteration 2/4
certificate_name: cert-5
key_type: ec521
subject_alt_name: "DNS:t2.example.com"
subject_alt_name_critical: false
account_key: account-ec384
challenge: http-01
modify_account: false
deactivate_authzs: true
force: false
remaining_days: 1
terms_agreed: false
account_email: ""
use_csr_content: false
- name: Store obtain results for cert 5b
ansible.builtin.set_fact:
cert_5_recreate_1: "{{ challenge_data is changed }}"
- name: Obtain cert 5 (should again by less days)
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 5, Iteration 3/4
certificate_name: cert-5
key_type: ec521
subject_alt_name: "DNS:t2.example.com"
subject_alt_name_critical: false
account_key: account-ec384
challenge: http-01
modify_account: false
deactivate_authzs: true
force: true
remaining_days: 1000
terms_agreed: false
account_email: ""
use_csr_content: true
acme_certificate_profile: "{{ '6days' if acme_supports_profiles else omit }}"
acme_certificate_include_renewal_cert_id: when_ari_supported
- name: Store obtain results for cert 5c
ansible.builtin.set_fact:
cert_5_recreate_2: "{{ challenge_data is changed }}"
cert_5c_obtain_results: "{{ certificate_obtain_result }}"
- name: Read account key (EC384)
ansible.builtin.slurp:
src: '{{ remote_tmp_dir }}/account-ec384.pem'
register: slurp_account_key
- name: Obtain cert 5 (should again by force)
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 5, Iteration 4/4
certificate_name: cert-5
key_type: ec521
subject_alt_name: "DNS:t2.example.com"
subject_alt_name_critical: false
account_key_content: "{{ slurp_account_key.content | b64decode }}"
challenge: http-01
modify_account: false
deactivate_authzs: true
force: true
remaining_days: 1
terms_agreed: false
account_email: ""
use_csr_content: false
- name: Store obtain results for cert 5d
ansible.builtin.set_fact:
cert_5_recreate_3: "{{ challenge_data is changed }}"
cert_5d_obtain_results: "{{ certificate_obtain_result }}"
- block:
- name: Obtain cert 6
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 6
certificate_name: cert-6
key_type: rsa
rsa_bits: "{{ default_rsa_key_size }}"
subject_alt_name: "DNS:example.org"
subject_alt_name_critical: false
account_key: account-ec256
challenge: tls-alpn-01
modify_account: true
deactivate_authzs: false
force: false
remaining_days: 1
terms_agreed: true
account_email: "example@example.org"
acme_expected_root_number: 0
select_chain:
# All intermediates have the same subject key identifier, so always
# the first chain will be found, and we need a second condition to
# make sure that the first condition actually works. (The second
# condition has been tested above.)
- test_certificates: first
subject_key_identifier: "{{ acme_intermediates[0].subject_key_identifier }}"
- test_certificates: last
issuer: "{{ acme_roots[1].subject }}"
use_csr_content: true
- name: Store obtain results for cert 6
ansible.builtin.set_fact:
cert_6_obtain_results: "{{ certificate_obtain_result }}"
cert_6_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}"
when: acme_intermediates[0].subject_key_identifier is defined
- block:
- name: Obtain cert 7
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 7
certificate_name: cert-7
key_type: rsa
rsa_bits: "{{ default_rsa_key_size }}"
subject_alt_name:
- "IP:127.0.0.1"
# - "IP:::1"
subject_alt_name_critical: false
account_key: account-ec256
challenge: http-01
modify_account: true
deactivate_authzs: false
force: false
remaining_days: 1
terms_agreed: true
account_email: "example@example.org"
acme_expected_root_number: 2
select_chain:
- test_certificates: last
authority_key_identifier: "{{ acme_roots[2].subject_key_identifier }}"
use_csr_content: false
- name: Store obtain results for cert 7
ansible.builtin.set_fact:
cert_7_obtain_results: "{{ certificate_obtain_result }}"
cert_7_alternate: "{{ 2 if select_crypto_backend == 'cryptography' else 0 }}"
when: acme_roots[2].subject_key_identifier is defined
- block:
- name: Obtain cert 8
ansible.builtin.include_tasks: obtain-cert.yml
vars:
certgen_title: Certificate 8
certificate_name: cert-8
key_type: rsa
rsa_bits: "{{ default_rsa_key_size_certificates }}"
subject_alt_name:
- "IP:127.0.0.1"
# IPv4 only since our test validation server doesn't work
# with IPv6 (thanks to Python's socketserver).
subject_alt_name_critical: false
account_key: account-ec256
challenge: tls-alpn-01
challenge_alpn_tls: acme_challenge_cert_helper
modify_account: true
deactivate_authzs: false
force: false
remaining_days: 1
terms_agreed: true
account_email: "example@example.org"
use_csr_content: true
- name: Store obtain results for cert 8
ansible.builtin.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 #######################################################################
# Make sure certificates are valid. Root certificate for Pebble equals the chain certificate.
- name: Verifying cert 1
ansible.builtin.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: true
register: cert_1_valid
- name: Verifying cert 2
ansible.builtin.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: true
register: cert_2_valid
- name: Verifying cert 3
ansible.builtin.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: true
register: cert_3_valid
- name: Verifying cert 4
ansible.builtin.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: true
register: cert_4_valid
- name: Verifying cert 5
ansible.builtin.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: true
register: cert_5_valid
- name: Verifying cert 6
ansible.builtin.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: true
register: cert_6_valid
when: acme_intermediates[0].subject_key_identifier is defined
- name: Verifying cert 7
ansible.builtin.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: true
register: cert_7_valid
when: acme_roots[2].subject_key_identifier is defined
- name: Verifying cert 8
ansible.builtin.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: true
register: cert_8_valid
when: cryptography_version.stdout is version('1.3', '>=')
# Dump certificate info
- name: Dumping cert 1
ansible.builtin.command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-1.pem" -noout -text'
register: cert_1_text
- name: Dumping cert 2
ansible.builtin.command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-2.pem" -noout -text'
register: cert_2_text
- name: Dumping cert 3
ansible.builtin.command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-3.pem" -noout -text'
register: cert_3_text
- name: Dumping cert 4
ansible.builtin.command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-4.pem" -noout -text'
register: cert_4_text
- name: Dumping cert 5
ansible.builtin.command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-5.pem" -noout -text'
register: cert_5_text
- name: Dumping cert 6
ansible.builtin.command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-6.pem" -noout -text'
register: cert_6_text
when: acme_intermediates[0].subject_key_identifier is defined
- name: Dumping cert 7
ansible.builtin.command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-7.pem" -noout -text'
register: cert_7_text
when: acme_roots[2].subject_key_identifier is defined
- name: Dumping cert 8
ansible.builtin.command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-8.pem" -noout -text'
register: cert_8_text
when: cryptography_version.stdout is version('1.3', '>=')
# Dump certificate info
- name: Dumping cert 1
community.crypto.x509_certificate_info:
path: "{{ remote_tmp_dir }}/cert-1.pem"
register: cert_1_info
- name: Dumping cert 2
community.crypto.x509_certificate_info:
path: "{{ remote_tmp_dir }}/cert-2.pem"
register: cert_2_info
- name: Dumping cert 3
community.crypto.x509_certificate_info:
path: "{{ remote_tmp_dir }}/cert-3.pem"
register: cert_3_info
- name: Dumping cert 4
community.crypto.x509_certificate_info:
path: "{{ remote_tmp_dir }}/cert-4.pem"
register: cert_4_info
- name: Dumping cert 5
community.crypto.x509_certificate_info:
path: "{{ remote_tmp_dir }}/cert-5.pem"
register: cert_5_info
- name: Dumping cert 6
community.crypto.x509_certificate_info:
path: "{{ remote_tmp_dir }}/cert-6.pem"
register: cert_6_info
when: acme_intermediates[0].subject_key_identifier is defined
- name: Dumping cert 7
community.crypto.x509_certificate_info:
path: "{{ remote_tmp_dir }}/cert-7.pem"
register: cert_7_info
when: acme_roots[2].subject_key_identifier is defined
- name: Dumping cert 8
community.crypto.x509_certificate_info:
path: "{{ remote_tmp_dir }}/cert-8.pem"
register: cert_8_info
when: cryptography_version.stdout is version('1.3', '>=')
## GET ACCOUNT ORDERS #########################################################################
- name: Don't retrieve orders
community.crypto.acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
acme_version: 2
acme_directory: "{{ acme_directory_url }}"
validate_certs: false
retrieve_orders: ignore
register: account_orders_not
- name: Retrieve orders as URL list (1/2)
community.crypto.acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
acme_version: 2
acme_directory: "{{ acme_directory_url }}"
validate_certs: false
retrieve_orders: url_list
register: account_orders_urls
- name: Retrieve orders as URL list (2/2)
community.crypto.acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ remote_tmp_dir }}/account-rsa.pem"
acme_version: 2
acme_directory: "{{ acme_directory_url }}"
validate_certs: false
retrieve_orders: url_list
register: account_orders_urls2
- name: Retrieve orders as object list (1/2)
community.crypto.acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
acme_version: 2
acme_directory: "{{ acme_directory_url }}"
validate_certs: false
retrieve_orders: object_list
register: account_orders_full
- name: Retrieve orders as object list (2/2)
community.crypto.acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ remote_tmp_dir }}/account-rsa.pem"
acme_version: 2
acme_directory: "{{ acme_directory_url }}"
validate_certs: false
retrieve_orders: object_list
register: account_orders_full2