--- ## SET UP ACCOUNT KEYS ######################################################################## - name: Create ECC256 account key command: openssl ecparam -name prime256v1 -genkey -out {{ output_dir }}/account-ec256.pem - name: Create ECC384 account key command: openssl ecparam -name secp384r1 -genkey -out {{ output_dir }}/account-ec384.pem - name: Create RSA-2048 account key command: openssl genrsa -out {{ output_dir }}/account-rsa2048.pem 2048 ## SET UP ACCOUNTS ############################################################################ - name: Make sure ECC256 account hasn't been created yet acme_account: select_crypto_backend: "{{ select_crypto_backend }}" acme_version: 2 acme_directory: https://{{ acme_host }}:14000/dir validate_certs: no account_key_src: "{{ output_dir }}/account-ec256.pem" state: absent - name: Create ECC384 account acme_account: select_crypto_backend: "{{ select_crypto_backend }}" acme_version: 2 acme_directory: https://{{ acme_host }}:14000/dir validate_certs: no account_key_content: "{{ lookup('file', output_dir ~ '/account-ec384.pem') }}" state: present allow_creation: yes terms_agreed: yes contact: - mailto:example@example.org - mailto:example@example.com - name: Create RSA-2048 account acme_account: select_crypto_backend: "{{ select_crypto_backend }}" acme_version: 2 acme_directory: https://{{ acme_host }}:14000/dir validate_certs: no account_key_src: "{{ output_dir }}/account-rsa2048.pem" state: present allow_creation: yes terms_agreed: yes contact: [] ## OBTAIN CERTIFICATES ######################################################################## - name: Obtain cert 1 include_tasks: obtain-cert.yml vars: certgen_title: Certificate 1 certificate_name: cert-1 key_type: rsa rsa_bits: 2048 subject_alt_name: "DNS:example.com" subject_alt_name_critical: no account_key: account-ec256 challenge: http-01 modify_account: yes deactivate_authzs: no force: no remaining_days: 10 terms_agreed: yes account_email: "example@example.org" retrieve_all_alternates: yes acme_expected_root_number: 1 select_chain: - test_certificates: last issuer: "{{ acme_roots[1].subject }}" - name: Store obtain results for cert 1 set_fact: cert_1_obtain_results: "{{ certificate_obtain_result }}" cert_1_alternate: "{{ 1 if select_crypto_backend == 'cryptography' else 0 }}" - name: Obtain cert 2 include_tasks: obtain-cert.yml vars: certgen_title: Certificate 2 certificate_name: cert-2 key_type: ec256 subject_alt_name: "DNS:*.example.com,DNS:example.com" subject_alt_name_critical: yes account_key: account-ec384 challenge: dns-01 modify_account: no deactivate_authzs: yes force: no remaining_days: 10 terms_agreed: no account_email: "" acme_expected_root_number: 0 retrieve_all_alternates: yes 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 }}" - name: Store obtain results for cert 2 set_fact: cert_2_obtain_results: "{{ certificate_obtain_result }}" cert_2_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}" - name: Obtain cert 3 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: no account_key_content: "{{ lookup('file', output_dir ~ '/account-rsa2048.pem') }}" challenge: dns-01 modify_account: no deactivate_authzs: no force: no remaining_days: 10 terms_agreed: no account_email: "" acme_expected_root_number: 0 retrieve_all_alternates: yes select_chain: - test_certificates: last subject: "{{ acme_roots[1].subject }}" - name: Store obtain results for cert 3 set_fact: cert_3_obtain_results: "{{ certificate_obtain_result }}" cert_3_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}" - name: Obtain cert 4 include_tasks: obtain-cert.yml vars: certgen_title: Certificate 4 certificate_name: cert-4 key_type: rsa rsa_bits: 2048 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: no account_key: account-rsa2048 challenge: http-01 modify_account: no deactivate_authzs: yes force: yes remaining_days: 10 terms_agreed: no account_email: "" acme_expected_root_number: 2 select_chain: - test_certificates: last issuer: "{{ acme_roots[2].subject }}" - test_certificates: last issuer: "{{ acme_roots[1].subject }}" - name: Store obtain results for cert 4 set_fact: cert_4_obtain_results: "{{ certificate_obtain_result }}" cert_4_alternate: "{{ 2 if select_crypto_backend == 'cryptography' else 0 }}" - name: Obtain cert 5 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: no account_key: account-ec384 challenge: http-01 modify_account: no deactivate_authzs: yes force: yes remaining_days: 10 terms_agreed: no account_email: "" - name: Store obtain results for cert 5a 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 10 days) 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: no account_key: account-ec384 challenge: http-01 modify_account: no deactivate_authzs: yes force: no remaining_days: 10 terms_agreed: no account_email: "" - name: Store obtain results for cert 5b set_fact: cert_5_recreate_1: "{{ challenge_data is changed }}" - name: Obtain cert 5 (should again by less days) 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: no account_key: account-ec384 challenge: http-01 modify_account: no deactivate_authzs: yes force: yes remaining_days: 1000 terms_agreed: no account_email: "" - name: Store obtain results for cert 5c set_fact: cert_5_recreate_2: "{{ challenge_data is changed }}" cert_5c_obtain_results: "{{ certificate_obtain_result }}" - name: Obtain cert 5 (should again by force) 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: no account_key_content: "{{ lookup('file', output_dir ~ '/account-ec384.pem') }}" challenge: http-01 modify_account: no deactivate_authzs: yes force: yes remaining_days: 10 terms_agreed: no account_email: "" - name: Store obtain results for cert 5d set_fact: cert_5_recreate_3: "{{ challenge_data is changed }}" cert_5d_obtain_results: "{{ certificate_obtain_result }}" - name: Obtain cert 6 include_tasks: obtain-cert.yml vars: certgen_title: Certificate 6 certificate_name: cert-6 key_type: rsa rsa_bits: 2048 subject_alt_name: "DNS:example.org" subject_alt_name_critical: no account_key: account-ec256 challenge: tls-alpn-01 modify_account: yes deactivate_authzs: no force: no remaining_days: 10 terms_agreed: yes 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: last subject_key_identifier: "{{ acme_intermediates[0].subject_key_identifier }}" - test_certificates: last issuer: "{{ acme_roots[1].subject }}" - name: Store obtain results for cert 6 set_fact: cert_6_obtain_results: "{{ certificate_obtain_result }}" cert_6_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}" - name: Obtain cert 7 include_tasks: obtain-cert.yml vars: certgen_title: Certificate 7 certificate_name: cert-7 key_type: rsa rsa_bits: 2048 subject_alt_name: - "IP:127.0.0.1" # - "IP:::1" subject_alt_name_critical: no account_key: account-ec256 challenge: http-01 modify_account: yes deactivate_authzs: no force: no remaining_days: 10 terms_agreed: yes account_email: "example@example.org" acme_expected_root_number: 2 select_chain: - test_certificates: last authority_key_identifier: "{{ acme_roots[2].subject_key_identifier }}" - name: Store obtain results for cert 7 set_fact: cert_7_obtain_results: "{{ certificate_obtain_result }}" cert_7_alternate: "{{ 2 if select_crypto_backend == 'cryptography' else 0 }}" - name: Obtain cert 8 include_tasks: obtain-cert.yml vars: certgen_title: Certificate 8 certificate_name: cert-8 key_type: rsa rsa_bits: 2048 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: no account_key: account-ec256 challenge: tls-alpn-01 challenge_alpn_tls: acme_challenge_cert_helper modify_account: yes deactivate_authzs: no force: no remaining_days: 10 terms_agreed: yes account_email: "example@example.org" - 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 }}" ## DISSECT CERTIFICATES ####################################################################### # Make sure certificates are valid. Root certificate for Pebble equals the chain certificate. - name: Verifying cert 1 command: openssl verify -CAfile "{{ output_dir }}/cert-1-root.pem" -untrusted "{{ output_dir }}/cert-1-chain.pem" "{{ output_dir }}/cert-1.pem" ignore_errors: yes register: cert_1_valid - name: Verifying cert 2 command: openssl verify -CAfile "{{ output_dir }}/cert-2-root.pem" -untrusted "{{ output_dir }}/cert-2-chain.pem" "{{ output_dir }}/cert-2.pem" ignore_errors: yes register: cert_2_valid - name: Verifying cert 3 command: openssl verify -CAfile "{{ output_dir }}/cert-3-root.pem" -untrusted "{{ output_dir }}/cert-3-chain.pem" "{{ output_dir }}/cert-3.pem" ignore_errors: yes register: cert_3_valid - name: Verifying cert 4 command: openssl verify -CAfile "{{ output_dir }}/cert-4-root.pem" -untrusted "{{ output_dir }}/cert-4-chain.pem" "{{ output_dir }}/cert-4.pem" ignore_errors: yes register: cert_4_valid - name: Verifying cert 5 command: openssl verify -CAfile "{{ output_dir }}/cert-5-root.pem" -untrusted "{{ output_dir }}/cert-5-chain.pem" "{{ output_dir }}/cert-5.pem" ignore_errors: yes register: cert_5_valid - name: Verifying cert 6 command: openssl verify -CAfile "{{ output_dir }}/cert-6-root.pem" -untrusted "{{ output_dir }}/cert-6-chain.pem" "{{ output_dir }}/cert-6.pem" ignore_errors: yes register: cert_6_valid - name: Verifying cert 7 command: openssl verify -CAfile "{{ output_dir }}/cert-7-root.pem" -untrusted "{{ output_dir }}/cert-7-chain.pem" "{{ output_dir }}/cert-7.pem" ignore_errors: yes register: cert_7_valid - name: Verifying cert 8 command: openssl verify -CAfile "{{ output_dir }}/cert-8-root.pem" -untrusted "{{ output_dir }}/cert-8-chain.pem" "{{ output_dir }}/cert-8.pem" ignore_errors: yes register: cert_8_valid # Dump certificate info - name: Dumping cert 1 command: openssl x509 -in "{{ output_dir }}/cert-1.pem" -noout -text register: cert_1_text - name: Dumping cert 2 command: openssl x509 -in "{{ output_dir }}/cert-2.pem" -noout -text register: cert_2_text - name: Dumping cert 3 command: openssl x509 -in "{{ output_dir }}/cert-3.pem" -noout -text register: cert_3_text - name: Dumping cert 4 command: openssl x509 -in "{{ output_dir }}/cert-4.pem" -noout -text register: cert_4_text - name: Dumping cert 5 command: openssl x509 -in "{{ output_dir }}/cert-5.pem" -noout -text register: cert_5_text - name: Dumping cert 6 command: openssl x509 -in "{{ output_dir }}/cert-6.pem" -noout -text register: cert_6_text - name: Dumping cert 7 command: openssl x509 -in "{{ output_dir }}/cert-7.pem" -noout -text register: cert_7_text - name: Dumping cert 8 command: openssl x509 -in "{{ output_dir }}/cert-8.pem" -noout -text register: cert_8_text # Dump certificate info - name: Dumping cert 1 openssl_certificate_info: path: "{{ output_dir }}/cert-1.pem" register: cert_1_info - name: Dumping cert 2 openssl_certificate_info: path: "{{ output_dir }}/cert-2.pem" register: cert_2_info - name: Dumping cert 3 openssl_certificate_info: path: "{{ output_dir }}/cert-3.pem" register: cert_3_info - name: Dumping cert 4 openssl_certificate_info: path: "{{ output_dir }}/cert-4.pem" register: cert_4_info - name: Dumping cert 5 openssl_certificate_info: path: "{{ output_dir }}/cert-5.pem" register: cert_5_info - name: Dumping cert 6 openssl_certificate_info: path: "{{ output_dir }}/cert-6.pem" register: cert_6_info - name: Dumping cert 7 openssl_certificate_info: path: "{{ output_dir }}/cert-7.pem" register: cert_7_info - name: Dumping cert 8 openssl_certificate_info: path: "{{ output_dir }}/cert-8.pem" register: cert_8_info ## GET ACCOUNT ORDERS ######################################################################### - name: Don't retrieve orders acme_account_info: select_crypto_backend: "{{ select_crypto_backend }}" account_key_src: "{{ output_dir }}/account-ec256.pem" acme_version: 2 acme_directory: https://{{ acme_host }}:14000/dir validate_certs: no retrieve_orders: ignore register: account_orders_not - name: Retrieve orders as URL list (1/2) acme_account_info: select_crypto_backend: "{{ select_crypto_backend }}" account_key_src: "{{ output_dir }}/account-ec256.pem" acme_version: 2 acme_directory: https://{{ acme_host }}:14000/dir validate_certs: no retrieve_orders: url_list register: account_orders_urls - name: Retrieve orders as URL list (2/2) acme_account_info: select_crypto_backend: "{{ select_crypto_backend }}" account_key_src: "{{ output_dir }}/account-ec384.pem" acme_version: 2 acme_directory: https://{{ acme_host }}:14000/dir validate_certs: no retrieve_orders: url_list register: account_orders_urls2 - name: Retrieve orders as object list (1/2) acme_account_info: select_crypto_backend: "{{ select_crypto_backend }}" account_key_src: "{{ output_dir }}/account-ec256.pem" acme_version: 2 acme_directory: https://{{ acme_host }}:14000/dir validate_certs: no retrieve_orders: object_list register: account_orders_full - name: Retrieve orders as object list (2/2) acme_account_info: select_crypto_backend: "{{ select_crypto_backend }}" account_key_src: "{{ output_dir }}/account-ec384.pem" acme_version: 2 acme_directory: https://{{ acme_host }}:14000/dir validate_certs: no retrieve_orders: object_list register: account_orders_full2