# -*- coding: utf-8 -*-
"""unittests for account.py"""

# pylint: disable=C0302, C0415, R0904, R0913, R0914, R0915, W0212
import os
import unittest
import configparser
import sys
import datetime
import socket
from unittest.mock import patch, MagicMock, Mock
import dns.resolver
import base64
import requests

sys.path.insert(0, ".")
sys.path.insert(1, "..")


class FakeDBStore(object):
    """face DBStore class needed for mocking"""

    profiles = {}
    header_info_field = "header_info_field"
    # pylint: disable=W0107, R0903
    pass


class TestACMEHandler(unittest.TestCase):
    """test class for ACMEHandler"""

    acme = None

    def setUp(self):
        """setup unittest"""
        import logging

        logging.basicConfig(level=logging.CRITICAL)
        from acme2certifier.acme_srv.helper import (
            b64decode_pad,
            b64_decode,
            b64_encode,
            b64_url_encode,
            b64_url_recode,
            b64_url_decode,
            convert_string_to_byte,
            convert_byte_to_string,
            decode_message,
            decode_deserialize,
            get_url,
            generate_random_string,
            signature_check,
            validate_email,
            uts_to_date_utc,
            date_to_uts_utc,
            load_config,
            cert_serial_get,
            cert_san_get,
            cert_dates_get,
            build_pem_file,
            date_to_datestr,
            datestr_to_date,
            dkeys_lower,
            csr_cn_get,
            cert_pubkey_get,
            csr_pubkey_get,
            url_get,
            url_get_with_own_dns,
            dns_server_list_load,
            csr_san_get,
            csr_san_byte_get,
            csr_extensions_get,
            fqdn_resolve,
            fqdn_in_san_check,
            sha256_hash,
            sha256_hash_hex,
            cert_der2pem,
            cert_pem2der,
            cert_extensions_get,
            csr_dn_get,
            logger_setup,
            logger_info,
            print_debug,
            jwk_thumbprint_get,
            allowed_gai_family,
            patched_create_connection,
            validate_csr,
            servercert_get,
            txt_get,
            proxystring_convert,
            proxy_check,
            handle_exception,
            ca_handler_load,
            eab_handler_load,
            hooks_load,
            error_dic_get,
            _logger_nonce_modify,
            _logger_certificate_modify,
            _logger_token_modify,
            _logger_challenges_modify,
            config_check,
            cert_issuer_get,
            cert_cn_get,
            string_sanitize,
            pembundle_to_list,
            certid_asn1_get,
            certid_check,
            certid_hex_get,
            v6_adjust,
            ipv6_chk,
            ip_validate,
            header_info_get,
            encode_url,
            uts_now,
            cert_ski_get,
            cert_aki_get,
            validate_fqdn,
            validate_ip,
            validate_identifier,
            client_parameter_validate,
            header_info_lookup,
            config_eab_profile_load,
            config_headerinfo_load,
            config_profile_load,
            config_proxy_load,
            allowed_domainlist_check,
            eab_profile_string_check,
            eab_profile_list_check,
            eab_profile_check,
            eab_profile_header_info_check,
            cryptography_version_get,
            cn_validate,
            csr_subject_get,
            eab_profile_subject_string_check,
            eab_profile_subject_check,
            csr_cn_lookup,
            request_operation,
            enrollment_config_log,
            config_enroll_config_log_load,
            config_allowed_domainlist_load,
            config_dns_server_list_load,
            config_async_mode_load,
            is_domain_whitelisted,
            allowed_domainlist_check,
            radomize_parameter_list,
            profile_lookup,
            eab_profile_revocation_check,
            handler_config_check,
            pkcs7_to_pem,
            config_dryrun_load,
            is_ip_whitelisted,
            config_allowed_iplist_load,
        )

        self.logger = logging.getLogger("test_a2c")
        self.allowed_gai_family = allowed_gai_family
        self.b64_decode = b64_decode
        self.b64_encode = b64_encode
        self.b64_url_encode = b64_url_encode
        self.b64_url_recode = b64_url_recode
        self.b64decode_pad = b64decode_pad
        self.build_pem_file = build_pem_file
        self.ca_handler_load = ca_handler_load
        self.cert_dates_get = cert_dates_get
        self.cert_extensions_get = cert_extensions_get
        self.certid_asn1_get = certid_asn1_get
        self.certid_check = certid_check
        self.cert_pubkey_get = cert_pubkey_get
        self.cert_san_get = cert_san_get
        self.cert_serial_get = cert_serial_get
        self.cert_aki_get = cert_aki_get
        self.cert_ski_get = cert_ski_get
        self.cert_issuer_get = cert_issuer_get
        self.cert_pem2der = cert_pem2der
        self.cert_der2pem = cert_der2pem
        self.cert_cn_get = cert_cn_get
        self.certid_hex_get = certid_hex_get
        self.config_check = config_check
        self.convert_byte_to_string = convert_byte_to_string
        self.convert_string_to_byte = convert_string_to_byte
        self.cryptography_version_get = cryptography_version_get
        self.csr_cn_get = csr_cn_get
        self.csr_dn_get = csr_dn_get
        self.csr_extensions_get = csr_extensions_get
        self.csr_pubkey_get = csr_pubkey_get
        self.csr_san_get = csr_san_get
        self.date_to_datestr = date_to_datestr
        self.date_to_uts_utc = date_to_uts_utc
        self.datestr_to_date = datestr_to_date
        self.decode_deserialize = decode_deserialize
        self.decode_message = decode_message
        self.dkeys_lower = dkeys_lower
        self.dns_server_list_load = dns_server_list_load
        self.eab_handler_load = eab_handler_load
        self.error_dic_get = error_dic_get
        self.fqdn_resolve = fqdn_resolve
        self.fqdn_in_san_check = fqdn_in_san_check
        self.generate_random_string = generate_random_string
        self.get_url = get_url
        self.client_parameter_validate = client_parameter_validate
        self.header_info_lookup = header_info_lookup
        self.hooks_load = hooks_load
        self.ipv6_chk = ipv6_chk
        self.jwk_thumbprint_get = jwk_thumbprint_get
        self.load_config = load_config
        self.logger_setup = logger_setup
        self.logger_info = logger_info
        self.logger_nonce_modify = _logger_nonce_modify
        self.logger_certificate_modify = _logger_certificate_modify
        self.logger_token_modify = _logger_token_modify
        self.logger_challenges_modify = _logger_challenges_modify
        self.patched_create_connection = patched_create_connection
        self.pembundle_to_list = pembundle_to_list
        self.print_debug = print_debug
        self.proxy_check = proxy_check
        self.servercert_get = servercert_get
        self.signature_check = signature_check
        self.txt_get = txt_get
        self.url_get = url_get
        self.url_get_with_own_dns = url_get_with_own_dns
        self.uts_to_date_utc = uts_to_date_utc
        self.validate_email = validate_email
        self.validate_ip = validate_ip
        self.validate_fqdn = validate_fqdn
        self.validate_identifier = validate_identifier
        self.validate_csr = validate_csr
        self.sha256_hash = sha256_hash
        self.sha256_hash_hex = sha256_hash_hex
        self.string_sanitize = string_sanitize
        self.proxystring_convert = proxystring_convert
        self.v6_adjust = v6_adjust
        self.handle_exception = handle_exception
        self.header_info_get = header_info_get
        self.csr_san_byte_get = csr_san_byte_get
        self.encode_url = encode_url
        self.uts_now = uts_now
        self.ip_validate = ip_validate
        self.config_headerinfo_load = config_headerinfo_load
        self.config_eab_profile_load = config_eab_profile_load
        self.config_allowed_domainlist_load = config_allowed_domainlist_load
        self.config_dns_server_list_load = config_dns_server_list_load
        self.allowed_domainlist_check = allowed_domainlist_check
        self.eab_profile_string_check = eab_profile_string_check
        self.eab_profile_list_check = eab_profile_list_check
        self.eab_profile_check = eab_profile_check
        self.eab_profile_header_info_check = eab_profile_header_info_check
        self.cn_validate = cn_validate
        self.csr_subject_get = csr_subject_get
        self.eab_profile_subject_string_check = eab_profile_subject_string_check
        self.eab_profile_subject_check = eab_profile_subject_check
        self.csr_cn_lookup = csr_cn_lookup
        self.request_operation = request_operation
        self.enrollment_config_log = enrollment_config_log
        self.config_enroll_config_log_load = config_enroll_config_log_load
        self.config_async_mode_load = config_async_mode_load
        self.is_domain_whitelisted = is_domain_whitelisted
        self.allowed_domainlist_check = allowed_domainlist_check
        self.radomize_parameter_list = radomize_parameter_list
        self.config_profile_load = config_profile_load
        self.config_proxy_load = config_proxy_load
        self.profile_lookup = profile_lookup
        self.b64_url_decode = b64_url_decode
        self.eab_profile_revocation_check = eab_profile_revocation_check
        self.handler_config_check = handler_config_check
        self.pkcs7_to_pem = pkcs7_to_pem
        self.dir_path = os.path.dirname(os.path.realpath(__file__))
        self.config_dryrun_load = config_dryrun_load
        self.is_ip_whitelisted = is_ip_whitelisted
        self.config_allowed_iplist_load = config_allowed_iplist_load

    def test_001_helper_b64decode_pad(self):
        """test b64decode_pad() method with a regular base64 encoded string"""
        self.assertEqual(
            "this-is-foo-correctly-padded",
            self.b64decode_pad(self.logger, "dGhpcy1pcy1mb28tY29ycmVjdGx5LXBhZGRlZA=="),
        )

    def test_002_helper_b64decode_pad(self):
        """test b64decode_pad() method with a regular base64 encoded string"""
        self.assertEqual(
            "this-is-foo-with-incorrect-padding",
            self.b64decode_pad(
                self.logger, "dGhpcy1pcy1mb28td2l0aC1pbmNvcnJlY3QtcGFkZGluZw"
            ),
        )

    def test_003_helper_b64decode_pad(self):
        """test b64 decoding failure"""
        self.assertEqual(
            "ERR: b64 decoding error", self.b64decode_pad(self.logger, "b")
        )

    def test_004_helper_decode_deserialize(self):
        """test successful deserialization of a b64 encoded string"""
        self.assertEqual(
            {"a": "b", "c": "d"},
            self.decode_deserialize(self.logger, "eyJhIiA6ICJiIiwgImMiIDogImQifQ=="),
        )

    def test_005_helper_decode_deserialize(self):
        """test failed deserialization of a b64 encoded string"""
        self.assertEqual(
            "ERR: Json decoding error",
            self.decode_deserialize(
                self.logger, "Zm9vLXdoaWNoLWNhbm5vdC1iZS1qc29uaXplZA=="
            ),
        )

    def test_006_helper_validate_email(self):
        """validate normal email"""
        self.assertTrue(self.validate_email(self.logger, "foo@example.com"))

    def test_007_helper_validate_email(self):
        """validate normal email"""
        self.assertTrue(self.validate_email(self.logger, "mailto:foo@example.com"))

    def test_008_helper_validate_email(self):
        """validate normal email"""
        self.assertTrue(self.validate_email(self.logger, "mailto: foo@example.com"))

    def test_009_helper_validate_email(self):
        """validate normal email"""
        self.assertTrue(
            self.validate_email(
                self.logger, ["mailto: foo@example.com", "mailto: bar@example.com"]
            )
        )

    def test_010_helper_validate_email(self):
        """validate normal email"""
        self.assertFalse(self.validate_email(self.logger, "example.com"))

    def test_011_helper_validate_email(self):
        """validate normal email"""
        self.assertFalse(self.validate_email(self.logger, "me@exam,ple.com"))

    def test_012_helper_validate_email(self):
        """validate normal email"""
        self.assertFalse(
            self.validate_email(
                self.logger, ["mailto: foo@exa,mple.com", "mailto: bar@example.com"]
            )
        )

    def test_013_helper_validate_email(self):
        """validate normal email"""
        self.assertFalse(
            self.validate_email(
                self.logger, ["mailto: foo@example.com", "mailto: bar@exa,mple.com"]
            )
        )

    def test_014_helper_signature_check(self):
        """successful validation of singature"""
        mkey = {
            "alg": "RS256",
            "e": "AQAB",
            "kty": "RSA",
            "n": "2CFMV4MK6Uo_2GQWa0KVWlzffgSDiLwur4ujSZkCRzbA3w5p1ABJgr7l_P84HpRv8R8rGL67hqmDJuT52mGD6fMVAhHPX5pSdtyZlQQuzpXonzNmHbG1DbMSiXrxg5jWVXchCxHx82wAt9Kf13O5ATxD0WOBB5FffpqQHh8zTf29jTL4vBd8N57ce17ZgNWl_EcoByjigqNFJcO0rrvrf6xyNaO9nbun4PAMJTLbfVa6CiEqjnjYMX80VYLH4fCqsAZgxIoli_D2j9P5Kq6KZZUL_bZ2QQV4UuwWZvh6tcA393YQLeMARnhWI6dqlZVdcU74NXi9NhSxcMkM8nZZ8Q",
        }
        message = '{"protected": "eyJub25jZSI6ICI3N2M3MmViMDE5NDc0YzBjOWIzODk5MmU4ZjRkMDIzYSIsICJ1cmwiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYWNjdC8xIiwgImFsZyI6ICJSUzI1NiIsICJraWQiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYWNjdC8xIn0","payload": "eyJzdGF0dXMiOiJkZWFjdGl2YXRlZCJ9","signature": "QYbMYZ1Dk8dHKqOwWBQHvWdnGD7donGZObb2Ry_Y5PsHpcTrj8Y2CM57SNVAR9V0ePg4vhK3-IbwYAKbhZV8jF7E-ylZaYm4PSQcumKLI55qvDiEvDiZ0gmjf_GAcsC40TwBa11lzR1u0dQYxOlQ_y9ak6705c5bM_V4_ttQeslJXCfVIQoV-sZS0Z6tJfy5dPVDR7JYG77bZbD3K-HCCaVbT7ilqcf00rA16lvw13zZnIgbcZsbW-eJ2BM_QxE24PGqc_vMfAxIiUG0VY7DqrKumLs91lHHTEie8I-CapH6AetsBhGtRcB6EL_Rn6qGQZK9YBpvoXANv_qF2-zQkQ"}'
        self.assertEqual((True, None), self.signature_check(self.logger, message, mkey))

    def test_015_helper_signature_check(self):
        """failed validatio of singature  wrong key"""
        mkey = {
            "alg": "rs256",
            "e": "AQAB",
            "kty": "RSA",
            "n": "zncgRHCp22-29g9FO4Hn02iyS1Fo4Y1tB-6cucH1yKSxM6bowjAaVa4HkAnIxgF6Zj9qLROgQR84YjMPeNkq8woBRz1aziDiTIOc0D2aXvLgZbuFGesvxoSGd6uyxjyyV7ONwZEpB8QtDW0I3shlhosKB3Ni1NFu55bPUP9RvxUdPzRRuhxUMHc1CXre1KR0eQmQdNZT6tgQVxpv2lb-iburBADjivBRyrI3k3NmXkYknBggAu8JInaFY4T8pVK0jTwP-f3-0eAV1bg99Rm7uXNXl7SKpQ3oGihwy2OK-XAc59v6C3n4Wq9QpzGkFWsOOlp4zEf13L3_UKugeExEqw",
        }
        message = '{"protected": "eyJub25jZSI6ICI3N2M3MmViMDE5NDc0YzBjOWIzODk5MmU4ZjRkMDIzYSIsICJ1cmwiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYWNjdC8xIiwgImFsZyI6ICJSUzI1NiIsICJraWQiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYWNjdC8xIn0","payload": "eyJzdGF0dXMiOiJkZWFjdGl2YXRlZCJ9","signature": "QYbMYZ1Dk8dHKqOwWBQHvWdnGD7donGZObb2Ry_Y5PsHpcTrj8Y2CM57SNVAR9V0ePg4vhK3-IbwYAKbhZV8jF7E-ylZaYm4PSQcumKLI55qvDiEvDiZ0gmjf_GAcsC40TwBa11lzR1u0dQYxOlQ_y9ak6705c5bM_V4_ttQeslJXCfVIQoV-sZS0Z6tJfy5dPVDR7JYG77bZbD3K-HCCaVbT7ilqcf00rA16lvw13zZnIgbcZsbW-eJ2BM_QxE24PGqc_vMfAxIiUG0VY7DqrKumLs91lHHTEie8I-CapH6AetsBhGtRcB6EL_Rn6qGQZK9YBpvoXANv_qF2-zQkQ"}'

        if int("%i%i" % (sys.version_info[0], sys.version_info[1])) <= 36:
            result = (
                False,
                "Verification failed for all signatures[\"Failed: [InvalidJWSSignature('Verification failed',)]\"]",
            )
        else:
            result = (
                False,
                "Verification failed for all signatures[\"Failed: [InvalidJWSSignature('Verification failed')]\"]",
            )

        self.assertEqual(result, self.signature_check(self.logger, message, mkey))

    def test_016_helper_signature_check(self):
        """failed validatio of singature  faulty key"""
        mkey = {
            "alg": "rs256",
            "e": "AQAB",
            "n": "zncgRHCp22-29g9FO4Hn02iyS1Fo4Y1tB-6cucH1yKSxM6bowjAaVa4HkAnIxgF6Zj9qLROgQR84YjMPeNkq8woBRz1aziDiTIOc0D2aXvLgZbuFGesvxoSGd6uyxjyyV7ONwZEpB8QtDW0I3shlhosKB3Ni1NFu55bPUP9RvxUdPzRRuhxUMHc1CXre1KR0eQmQdNZT6tgQVxpv2lb-iburBADjivBRyrI3k3NmXkYknBggAu8JInaFY4T8pVK0jTwP-f3-0eAV1bg99Rm7uXNXl7SKpQ3oGihwy2OK-XAc59v6C3n4Wq9QpzGkFWsOOlp4zEf13L3_UKugeExEqw",
        }
        message = '{"protected": "eyJub25jZSI6ICI3N2M3MmViMDE5NDc0YzBjOWIzODk5MmU4ZjRkMDIzYSIsICJ1cmwiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYWNjdC8xIiwgImFsZyI6ICJSUzI1NiIsICJraWQiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYWNjdC8xIn0","payload": "eyJzdGF0dXMiOiJkZWFjdGl2YXRlZCJ9","signature": "QYbMYZ1Dk8dHKqOwWBQHvWdnGD7donGZObb2Ry_Y5PsHpcTrj8Y2CM57SNVAR9V0ePg4vhK3-IbwYAKbhZV8jF7E-ylZaYm4PSQcumKLI55qvDiEvDiZ0gmjf_GAcsC40TwBa11lzR1u0dQYxOlQ_y9ak6705c5bM_V4_ttQeslJXCfVIQoV-sZS0Z6tJfy5dPVDR7JYG77bZbD3K-HCCaVbT7ilqcf00rA16lvw13zZnIgbcZsbW-eJ2BM_QxE24PGqc_vMfAxIiUG0VY7DqrKumLs91lHHTEie8I-CapH6AetsBhGtRcB6EL_Rn6qGQZK9YBpvoXANv_qF2-zQkQ"}'
        if sys.version_info[0] < 3:
            self.assertEqual(
                (False, "Unknown type \"None\", valid types are: ['RSA', 'EC', 'oct']"),
                self.signature_check(self.logger, message, mkey),
            )
        else:
            self.assertEqual(
                (
                    False,
                    "Unknown type \"None\", valid types are: ['EC', 'RSA', 'oct', 'OKP']",
                ),
                self.signature_check(self.logger, message, mkey),
            )

    def test_017_helper_signature_check(self):
        """failed validatio of singature  no key"""
        mkey = {}
        message = '{"protected": "eyJub25jZSI6ICI3N2M3MmViMDE5NDc0YzBjOWIzODk5MmU4ZjRkMDIzYSIsICJ1cmwiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYWNjdC8xIiwgImFsZyI6ICJSUzI1NiIsICJraWQiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYWNjdC8xIn0","payload": "eyJzdGF0dXMiOiJkZWFjdGl2YXRlZCJ9","signature": "QYbMYZ1Dk8dHKqOwWBQHvWdnGD7donGZObb2Ry_Y5PsHpcTrj8Y2CM57SNVAR9V0ePg4vhK3-IbwYAKbhZV8jF7E-ylZaYm4PSQcumKLI55qvDiEvDiZ0gmjf_GAcsC40TwBa11lzR1u0dQYxOlQ_y9ak6705c5bM_V4_ttQeslJXCfVIQoV-sZS0Z6tJfy5dPVDR7JYG77bZbD3K-HCCaVbT7ilqcf00rA16lvw13zZnIgbcZsbW-eJ2BM_QxE24PGqc_vMfAxIiUG0VY7DqrKumLs91lHHTEie8I-CapH6AetsBhGtRcB6EL_Rn6qGQZK9YBpvoXANv_qF2-zQkQ"}'
        self.assertEqual(
            (False, "No key specified."),
            self.signature_check(self.logger, message, mkey),
        )

    def test_018_helper_uts_to_date_utc(self):
        """test uts_to_date_utc for a given format"""
        self.assertEqual("2018-12-01", self.uts_to_date_utc(1543640400, "%Y-%m-%d"))

    def test_019_helper_uts_to_date_utc(self):
        """test uts_to_date_utc without format"""
        self.assertEqual("2018-12-01T05:00:00Z", self.uts_to_date_utc(1543640400))

    def test_020_helper_date_to_uts_utc(self):
        """test date_to_uts_utc for a given format"""
        self.assertEqual(1543622400, self.date_to_uts_utc("2018-12-01", "%Y-%m-%d"))

    def test_021_helper_date_to_uts_utc(self):
        """test date_to_uts_utc without format"""
        self.assertEqual(1543640400, self.date_to_uts_utc("2018-12-01T05:00:00"))

    def test_022_helper_date_to_uts_utc(self):
        """test date_to_uts_utc with a datestring"""
        timestamp = datetime.datetime(2018, 12, 1, 5, 0, 1)
        self.assertEqual(1543640401, self.date_to_uts_utc(timestamp))

    def test_023_helper_generate_random_string(self):
        """test date_to_uts_utc without format"""
        self.assertEqual(5, len(self.generate_random_string(self.logger, 5)))

    def test_024_helper_generate_random_string(self):
        """test date_to_uts_utc without format"""
        self.assertEqual(15, len(self.generate_random_string(self.logger, 15)))

    def test_025_helper_b64_url_recode(self):
        """test base64url recode to base64 - add padding for 1 char"""
        self.assertEqual("fafafaf=", self.b64_url_recode(self.logger, "fafafaf"))

    def test_026_helper_b64_url_recode(self):
        """test base64url recode to base64 - add padding for 2 char"""
        self.assertEqual("fafafa==", self.b64_url_recode(self.logger, "fafafa"))

    def test_027_helper_b64_url_recode(self):
        """test base64url recode to base64 - add padding for 3 char"""
        self.assertEqual("fafaf===", self.b64_url_recode(self.logger, "fafaf"))

    def test_028_helper_b64_url_recode(self):
        """test base64url recode to base64 - no padding"""
        self.assertEqual("fafafafa", self.b64_url_recode(self.logger, "fafafafa"))

    def test_029_helper_b64_url_recode(self):
        """test base64url replace - with + and pad"""
        self.assertEqual("fafa+f==", self.b64_url_recode(self.logger, "fafa-f"))

    def test_030_helper_b64_url_recode(self):
        """test base64url replace _ with / and pad"""
        self.assertEqual("fafa/f==", self.b64_url_recode(self.logger, "fafa_f"))

    def test_031_helper_b64_url_recode(self):
        """test base64url recode to base64 - add padding for 1 char"""
        self.assertEqual("fafafaf=", self.b64_url_recode(self.logger, b"fafafaf"))

    def test_032_helper_b64_url_recode(self):
        """test base64url recode to base64 - add padding for 2 char"""
        self.assertEqual("fafafa==", self.b64_url_recode(self.logger, b"fafafa"))

    def test_033_helper_b64_url_recode(self):
        """test base64url recode to base64 - add padding for 3 char"""
        self.assertEqual("fafaf===", self.b64_url_recode(self.logger, b"fafaf"))

    def test_034_helper_b64_url_recode(self):
        """test base64url recode to base64 - no padding"""
        self.assertEqual("fafafafa", self.b64_url_recode(self.logger, b"fafafafa"))

    def test_035_helper_b64_url_recode(self):
        """test base64url replace - with + and pad"""
        self.assertEqual("fafa+f==", self.b64_url_recode(self.logger, b"fafa-f"))

    def test_036_helper_b64_url_recode(self):
        """test base64url replace _ with / and pad"""
        self.assertEqual("fafa/f==", self.b64_url_recode(self.logger, b"fafa_f"))

    def test_037_helper_b64_url_recode(self):
        """test base64url replace _ with / and pad"""
        self.assertEqual("fafa/f==", self.b64_url_recode(self.logger, b"fafa_f"))

    def test_038_helper_decode_message(self):
        """decode message with empty payload - certbot issue"""
        data_dic = '{"protected": "eyJub25jZSI6ICIyNmU2YTQ2ZWZhZGQ0NzdkOTA4ZDdjMjAxNGU0OWIzNCIsICJ1cmwiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYXV0aHovUEcxODlGRnpmYW8xIiwgImtpZCI6ICJodHRwOi8vbGFwdG9wLm5jbG0tc2FtYmEubG9jYWwvYWNtZS9hY2N0L3l1WjFHVUpiNzZaayIsICJhbGciOiAiUlMyNTYifQ", "payload": "", "signature": "ZW5jb2RlZF9zaWduYXR1cmU="}'
        e_result = (
            True,
            None,
            {
                "nonce": "26e6a46efadd477d908d7c2014e49b34",
                "url": "http://laptop.nclm-samba.local/acme/authz/PG189FFzfao1",
                "alg": "RS256",
                "kid": "http://laptop.nclm-samba.local/acme/acct/yuZ1GUJb76Zk",
            },
            {},
            b"encoded_signature",
        )
        self.assertEqual(e_result, self.decode_message(self.logger, data_dic))

    def test_039_helper_decode_message(self):
        """decode message with empty payload - certbot issue"""
        data_dic = '{"protected": "eyJub25jZSI6ICIyNmU2YTQ2ZWZhZGQ0NzdkOTA4ZDdjMjAxNGU0OWIzNCIsICJ1cmwiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYXV0aHovUEcxODlGRnpmYW8xIiwgImtpZCI6ICJodHRwOi8vbGFwdG9wLm5jbG0tc2FtYmEubG9jYWwvYWNtZS9hY2N0L3l1WjFHVUpiNzZaayIsICJhbGciOiAiUlMyNTYifQ", "payload": "eyJmb28iOiAiYmFyMSJ9", "signature": "ZW5jb2RlZF9zaWduYXR1cmU="}'
        e_result = (
            True,
            None,
            {
                "nonce": "26e6a46efadd477d908d7c2014e49b34",
                "url": "http://laptop.nclm-samba.local/acme/authz/PG189FFzfao1",
                "alg": "RS256",
                "kid": "http://laptop.nclm-samba.local/acme/acct/yuZ1GUJb76Zk",
            },
            {"foo": "bar1"},
            b"encoded_signature",
        )
        self.assertEqual(e_result, self.decode_message(self.logger, data_dic))

    @patch("json.loads")
    def test_040_helper_decode_message(self, mock_json):
        """decode message with with exception during decoding"""
        mock_json.side_effect = Exception("exc_mock_json")
        data_dic = '{"protected": "eyJub25jZSI6ICIyNmU2YTQ2ZWZhZGQ0NzdkOTA4ZDdjMjAxNGU0OWIzNCIsICJ1cmwiOiAiaHR0cDovL2xhcHRvcC5uY2xtLXNhbWJhLmxvY2FsL2FjbWUvYXV0aHovUEcxODlGRnpmYW8xIiwgImtpZCI6ICJodHRwOi8vbGFwdG9wLm5jbG0tc2FtYmEubG9jYWwvYWNtZS9hY2N0L3l1WjFHVUpiNzZaayIsICJhbGciOiAiUlMyNTYifQ", "payload": "", "signature": "ZW5jb2RlZF9zaWduYXR1cmU="}'
        if int("%i%i" % (sys.version_info[0], sys.version_info[1])) < 37:
            result = "ERROR:test_a2c:Error during message decoding Invalid JWS Object [Invalid format]"
            e_result = (False, "Invalid JWS Object [Invalid format]", {}, {}, None)
        else:
            result = "ERROR:test_a2c:Error during message decoding Invalid JWS Object [Invalid format]"
            e_result = (False, "Invalid JWS Object [Invalid format]", {}, {}, None)
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(e_result, self.decode_message(self.logger, data_dic))
        self.assertIn(result, lcm.output)

    def test_041_helper_cert_serial_get(self):
        """test cert_serial_get"""
        cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u
                ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw
                FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
                ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq
                HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC
                7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y
                dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er
                1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+
                FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z
                zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7
                LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB
                AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02
                5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm
                TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h
                bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR
                fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H
                t+eRUDECE+0UnjyeCjTn3EU="""
        self.assertEqual(10, self.cert_serial_get(self.logger, cert))

    def test_042_helper_cert_serial_get(self):
        """test cert_serial_get"""
        cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u
                ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw
                FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
                ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq
                HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC
                7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y
                dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er
                1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+
                FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z
                zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7
                LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB
                AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02
                5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm
                TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h
                bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR
                fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H
                t+eRUDECE+0UnjyeCjTn3EU="""
        self.assertEqual(10, self.cert_serial_get(self.logger, cert, hexformat=False))

    def test_043_helper_cert_serial_get(self):
        """test cert_serial_get"""
        cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u
                ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw
                FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
                ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq
                HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC
                7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y
                dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er
                1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+
                FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z
                zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7
                LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB
                AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02
                5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm
                TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h
                bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR
                fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H
                t+eRUDECE+0UnjyeCjTn3EU="""
        self.assertEqual("0a", self.cert_serial_get(self.logger, cert, hexformat=True))

    def test_044_helper_cert_issuer_get(self):
        """test cert_issuer_get"""
        cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u
                ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw
                FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
                ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq
                HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC
                7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y
                dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er
                1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+
                FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z
                zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7
                LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB
                AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02
                5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm
                TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h
                bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR
                fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H
                t+eRUDECE+0UnjyeCjTn3EU="""
        self.assertEqual("CN=foo.example.com", self.cert_issuer_get(self.logger, cert))

    def test_045_helper_cert_san_get(self):
        """test cert_san_get for a single SAN"""
        cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u
                ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw
                FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
                ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq
                HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC
                7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y
                dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er
                1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+
                FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z
                zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7
                LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB
                AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02
                5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm
                TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h
                bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR
                fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H
                t+eRUDECE+0UnjyeCjTn3EU="""
        self.assertEqual(["DNS:foo.example.com"], self.cert_san_get(self.logger, cert))

    def test_046_helper_cert_san_get(self):
        """test cert_san_get for a multiple SAN of type DNS"""
        cert = """MIIDIzCCAgugAwIBAgICBZgwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAxMPZm9v
                LmV4YW1wbGUuY29tMB4XDTE5MDEyMDE3MDkxMVoXDTE5MDIxOTE3MDkxMVowGjEY
                MBYGA1UEAxMPZm9vLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
                MIIBCgKCAQEA+EM+gzAyjegQSRbJI+qZJhuAGM9i48xvIfuOQHleXoJPjV+8VZRV
                KDljZNXdNT5Zi7K6HY9C622NOV7QefB6zTtm6mSY08ypNsaeorhIvJdnpaJ9gAGH
                YeQqJ04fL099kiRXJAv8gT8wdpiekg2KEU4wlXMIRfSHiiB37yjcqUzXl6XYYKGe
                2USMpDfliXL3o8TW2KByGUdCzXUdNbMgzRXwYxkX2+xV2f0vn8NyXHiHg9yJRof2
                HTjyvAcXN5Nr987slq/Ex5lXLtpB861Ov3ZbwxyzREjmreZBlze7KTfP5IY66XuN
                Mvhi7AAs0cLTd3SNjpppE/yvUi5q5gfhXQIDAQABo3MwcTAfBgNVHSMEGDAWgBSl
                YnpKQw12MmEMpvsTEeQi17UsnDAdBgNVHQ4EFgQUpWJ6SkMNdjJhDKb7ExHkIte1
                LJwwLwYDVR0RBCgwJoIRZm9vLTIuZXhhbXBsZS5jb22CEWZvby0xLmV4YW1wbGUu
                Y29tMA0GCSqGSIb3DQEBCwUAA4IBAQASA20TtMPXIHH10dikLhFuI14EOtZzXvCx
                kGlJw9/5JuvVKLsL1wd8BC9o/lg8apDqsrDZ/+0Nc8g3Z9HRN99vcLsVDdT27DkM
                BslfXdN/qBhKAp3m7jw29uijX5fss+Wz9iHfHciUjVyMJ4DoFxHYPbMWQG8XEUKR
                TP6Gp79DzCiPKFt52Y8yVikIET4fnyRzU8kGKLuPoIt+EQQzpG26qWAjeNHAASEM
                keiA+tedMWzydX52B+tGg+l2svxg34apIBDjK8pF+8ZxTt5yjVUa10GbpffJuiEh
                NWQddOR8IHg+v6lWc9BtuuKK5ubsg6XOiEjhhr42AKViKalX1i4+"""
        self.assertEqual(
            ["DNS:foo-2.example.com", "DNS:foo-1.example.com"],
            self.cert_san_get(self.logger, cert),
        )

    def test_047_helper_cert_san_get(self):
        """test cert_san_get for a multiple SAN of type DNS"""
        cert = """MIIDaDCCAVCgAwIBAgIICwL0UBNcUakwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMzA3MTkxODU5NDRaFw0yNDA3MTgxODU5NDRaMBkxFzAVBgNVBAMTDjE5Mi4xNjguMTQuMTMxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEN626lPpwBt4SEvdf5Tb0BpP1tl9KiFE/9xCIyYPsi9VXVDq/EcwO3CRp4fy+3bhZj6i43DdnluETcx8ZR2XyE6NuMGwwHQYDVR0OBBYEFBp+ZupvT2BB92sDkxy2GffHXDRLMB8GA1UdIwQYMBaAFL/ejo4GIiKrrUPI3dRPqKtIQT7VMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMA8GA1UdEQQIMAaHBMCoDoMwDQYJKoZIhvcNAQELBQADggIBAFpq5RWGP4kDRnRjq8pte87bGS9LEmSlGOA8HlQZ+kjAoTunNN7/gvDch4F/CIl1N8cbQ/Ty1vx9CznTpQ39c2LNMILnjNHqQpYRIgLSBvCm26pAdlmicy6zdGlRKaePoMXINw4csDZ4REERg/c21ANhFclYyWWUM987bHZuBZJM8zBfR98ZnOzuQMRb5xztRlXSvddW4qEyKihl+5wPduaF8hDui4wbDFW6pUE9DWO/S1m37Tshh1O3NLlAlaMMwLsYaGkW7yzM4OrzmghJCRtdF9lbYYqHoKxLVWyCRF/pXqqQ/y+k4sN0MeZ7Wk4dI18aGHTGEzu6GSynNptyCQNsoTYexDA/rx57ukX7TqrU5JU/VyrKYD+M/rsLMj3vY4YmmH4W12IhAxa6+UmGG9ixHKpTgLVLRJDdzPMLY+IdI9WHdo7nHDOsaKvrFWqmvsCxT214jN0fVkOTMazG4ILg4DZhMWh8QxGULR7ul2oYnlyGUXiag7qLjNu1/RltJg9sp+ZxVC7RWaoCwxp6CIT95wrUAFTt9NBkccafsQKsF2ZtrUNZ8Z7B3y6hzr9d6rWlZCKlcr/ZNSOnrRTwuCz5HL3Gd2/DfyZUmy5U1+URbktMIdddlV5jaeSpwFZI8Xga4cYJAE7xjVq8HN3jbZ6m4PyylfaQfXisozKRECs4"""
        self.assertEqual(["IP:192.168.14.131"], self.cert_san_get(self.logger, cert))

    def test_048_helper_cert_san_get(self):
        """test cert_san_get for a multiple SAN of type DNS"""
        cert = """MIIDezCCAWOgAwIBAgIIIAuZLppuFT4wDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMzA3MjAwNDIxMTlaFw0yNDA3MTkwNDIxMTlaMBkxFzAVBgNVBAMTDjE5Mi4xNjguMTQuMTMxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQTs6Bra1zfVSiReD4AYj8HCKdcaMO5WsgB0zhpVu3HuSQSIQHC8CMe8haCywjYisbbWeDzT654tc674/MjScraOBgDB+MB0GA1UdDgQWBBQQa+M+3oTsdKTSB/Rt3Dk7/Vy0YzAfBgNVHSMEGDAWgBS/3o6OBiIiq61DyN3UT6irSEE+1TALBgNVHQ8EBAMCA+gwDAYDVR0TAQH/BAIwADAhBgNVHREEGjAYghBmb29iYXIuYmFyLmxvY2FshwTAqA6DMA0GCSqGSIb3DQEBCwUAA4ICAQCcevAczULbl5Le/xI1LSQ/PSsROjOZHUjlWf5bRs53aTM6wMqDBsFGdLzTN5vzWqVjie1Nzu8XGSEEuF0L/2bltGgYiYQqD4HKJedEEbYxQbg77o9JLp52MltvXGRH5gYGSGPZbuQ8QANvDn6FqBZjskOtED8SZGGt5spgxK7eguoJoQken68TgdZptL6l6eryTgouPbG0j5vTPPxuZpqxM9vQa4ADyqyvOKRMkZC98IbruChlCtFztILJPkvNx8Gbmlzv201uW9/9mNzcV8vVtlcB+Ftb/+sCfYuU/ShwUuOxOLE7+OKjLlalfniNwqx2l6f30nvvsa11vQc/Rwy1Z+vv96EzyF+GthMx2qLIG4eLLbISATwUfpR0UcLMtr83LRzB578rxrtwcgB5s+AWSDsYEKnzXabQdX1cEuiM3iEdlZ7McFzRvwElObhoDDOqOjGALWmdboox6dDskpQEhe6JALsj3mH07017h5T3W3PvqWD2IAsqH+WTuxCTmfjbqqoAz/Zt2ipIAFtSk79WvWwth/K+xtYhmuoe2+ygocqa9tF9AyoihImSEk1EjXvqKqRLPZwg41C3WKvLlg57fpRFZYR1W28ZqAqqVNf8MMHcsHdZ7koMBhIKKnSe/HdLWm7ghVjAEdYVYvOcOZHzxXBmnV/6ZLRQXu2XQnATJw=="""
        self.assertEqual(
            ["DNS:foobar.bar.local", "IP:192.168.14.131"],
            self.cert_san_get(self.logger, cert),
        )

    def test_049_helper_cert_san_get(self):
        """test cert_san_get for a multiple SAN of type DNS"""
        cert = """MIIDezCCAWOgAwIBAgIIIAuZLppuFT4wDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMzA3MjAwNDIxMTlaFw0yNDA3MTkwNDIxMTlaMBkxFzAVBgNVBAMTDjE5Mi4xNjguMTQuMTMxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQTs6Bra1zfVSiReD4AYj8HCKdcaMO5WsgB0zhpVu3HuSQSIQHC8CMe8haCywjYisbbWeDzT654tc674/MjScraOBgDB+MB0GA1UdDgQWBBQQa+M+3oTsdKTSB/Rt3Dk7/Vy0YzAfBgNVHSMEGDAWgBS/3o6OBiIiq61DyN3UT6irSEE+1TALBgNVHQ8EBAMCA+gwDAYDVR0TAQH/BAIwADAhBgNVHREEGjAYghBmb29iYXIuYmFyLmxvY2FshwTAqA6DMA0GCSqGSIb3DQEBCwUAA4ICAQCcevAczULbl5Le/xI1LSQ/PSsROjOZHUjlWf5bRs53aTM6wMqDBsFGdLzTN5vzWqVjie1Nzu8XGSEEuF0L/2bltGgYiYQqD4HKJedEEbYxQbg77o9JLp52MltvXGRH5gYGSGPZbuQ8QANvDn6FqBZjskOtED8SZGGt5spgxK7eguoJoQken68TgdZptL6l6eryTgouPbG0j5vTPPxuZpqxM9vQa4ADyqyvOKRMkZC98IbruChlCtFztILJPkvNx8Gbmlzv201uW9/9mNzcV8vVtlcB+Ftb/+sCfYuU/ShwUuOxOLE7+OKjLlalfniNwqx2l6f30nvvsa11vQc/Rwy1Z+vv96EzyF+GthMx2qLIG4eLLbISATwUfpR0UcLMtr83LRzB578rxrtwcgB5s+AWSDsYEKnzXabQdX1cEuiM3iEdlZ7McFzRvwElObhoDDOqOjGALWmdboox6dDskpQEhe6JALsj3mH07017h5T3W3PvqWD2IAsqH+WTuxCTmfjbqqoAz/Zt2ipIAFtSk79WvWwth/K+xtYhmuoe2+ygocqa9tF9AyoihImSEk1EjXvqKqRLPZwg41C3WKvLlg57fpRFZYR1W28ZqAqqVNf8MMHcsHdZ7koMBhIKKnSe/HdLWm7ghVjAEdYVYvOcOZHzxXBmnV/6ZLRQXu2XQnATJw=="""
        self.assertEqual(
            ["DNS:foobar.bar.local", "IP:192.168.14.131"],
            self.cert_san_get(self.logger, cert),
        )

    def test_050_helper_cert_san_get(self):
        """test cert_san_get for a single SAN"""
        cert = """
-----BEGIN CERTIFICATE-----
MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u
ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw
FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq
HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC
7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y
dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er
1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+
FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z
zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7
LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB
AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02
5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm
TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h
bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR
fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H
t+eRUDECE+0UnjyeCjTn3EU=
-----END CERTIFICATE-----
                """
        self.assertEqual(
            ["DNS:foo.example.com"],
            self.cert_san_get(self.logger, cert, recode=False),
        )

    def test_051_helper_cert_san_get(self):
        """test cert_san_get for a single SAN and recode = False"""
        cert = """-----BEGIN X509 CERTIFICATE-----
MIIE2zCCAsOgAwIBAgIPAXI102H4bCWEkhD2SaLsMA0GCSqGSIb3DQEBDQUAMDIx
CzAJBgNVBAYTAkRFMQ4wDAYDVQQKEwVOb2tpYTETMBEGA1UEAwwKbmNtX3N1Yl9j
YTAeFw0yMDA1MjEwNTMyMjVaFw0yMDA2MjAyMzU5NTlaMBkxFzAVBgNVBAMTDmZv
bzEuYmFyLmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+
z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN
+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOL
hjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MF
o+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgba
j94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xo
aygpd9+UHCREhcOu/wIDAQABo4IBBTCCAQEwHwYDVR0jBBgwFoAUEZ+5Dp2l8KCZ
zHhwr3965P6xxsswHQYDVR0OBBYEFKsuSjgZZMl9vZeBB0wks4Wbg4PhMAsGA1Ud
DwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDBUBgNVHR8ETTBLMEmg
R6BFhkNodHRwOi8vc3J2Lm5jbG0tc2FtYmEubG9jYWw6ODA4MC9jcmwtYXMtZGVy
L2N1cnJlbnRjcmwtODcuY3JsP2lkPTg3MEEGCCsGAQUFBwEBBDUwMzAxBggrBgEF
BQcwAYYlaHR0cDovL3Nydi5uY2xtLXNhbWJhLmxvY2FsOjgwOTAvY2EyLzANBgkq
hkiG9w0BAQ0FAAOCAgEAgpfWOM8fWlkwSbWtgnAKnu8GNMteOckWS1gMydOhokhY
PZdkpL8uoMWRahyjhmAH85TtHdydVaQ9NNBUTsbiOqkN2jPurDdzgfUs2gAwoR05
MkHVWI1+C3lHAVlqPWYld+6Kl3lnEjy3jFSMugTuq5h79f0KxGle7W568Xg+zI3R
Ry1dRggR6W2G9L+7Ez8Y+H/8P/gjbTO1GGYoXI4ISQl3EinL/X7XpYnQ3o14uDLb
m/h+YyLfi03m8tLJQPM7soDAZx6qI/1V4H/VT1VEKBCiec8w580rIH6GSrjUkddp
wd0p74B8xwmt9zA+gBV3Js72PBy9mdcMIvYIO3otmN2jQL8PC1B8VNEmf0l8a5wq
07qftQEI82vcrLG8Dgy7R9AxrIxd1xnZOTrcOo3dU+blAehAJZWT2B0B8XyoGk2/
CiMCwOQijMgp97tjnuQ3dkRhu50kUN5LCa9jU2ongXj0+28mEKZ5rAQUBQmAMITR
hTkTB1OxdpFMxyg83OZdYu/xit9YfVB0AAyarqjTst/y79UkExfEf0sAARBiffkx
PZwtZpoz736yvIqanX6u2zUHLDzSRZXOZHY6pxANqoH6howxqGkI3FMjeDbDUln7
/TEtRju77ONV1X+8iPYrnQqTRoR3a3IwT8Cz/HErNM6aNCvPVPqakZXZrcpXILY=
-----END X509 CERTIFICATE-----"""

        self.assertEqual(
            ["DNS:foo1.bar.local"], self.cert_san_get(self.logger, cert, recode=False)
        )

    @patch("acme2certifier.acme_srv.helpers.certificates.cert_load")
    def test_052_helper_cert_san_get(self, mock_certload):
        """test cert_san_get for a single SAN and recode = False"""
        cert = "cert"
        mock_certload.return_value = "mock_csrload"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.cert_san_get(self.logger, cert, recode=False))
        self.assertIn(
            "ERROR:test_a2c:Error while getting SANs from certificate: 'str' object has no attribute 'extensions'",
            lcm.output,
        )

    def test_053_helper_build_pem_file(self):
        """test build_pem_file without exsting content"""
        existing = None
        cert = "cert"
        self.assertEqual(
            "-----BEGIN CERTIFICATE-----\ncert\n-----END CERTIFICATE-----\n",
            self.build_pem_file(self.logger, existing, cert, True),
        )

    def test_054_helper_build_pem_file(self):
        """test build_pem_file with exsting content"""
        existing = "existing"
        cert = "cert"
        self.assertEqual(
            "existing-----BEGIN CERTIFICATE-----\ncert\n-----END CERTIFICATE-----\n",
            self.build_pem_file(self.logger, existing, cert, True),
        )

    def test_055_helper_build_pem_file(self):
        """test build_pem_file with long cert (to test wrap)"""
        existing = None
        cert = (
            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        )
        self.assertEqual(
            "-----BEGIN CERTIFICATE-----\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\naaaaaaaaa\n-----END CERTIFICATE-----\n",
            self.build_pem_file(self.logger, existing, cert, True),
        )

    def test_056_helper_build_pem_file(self):
        """test build_pem_file with long cert (to test wrap)"""
        existing = None
        cert = (
            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        )
        self.assertEqual(
            "-----BEGIN CERTIFICATE-----\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n-----END CERTIFICATE-----\n",
            self.build_pem_file(self.logger, existing, cert, False),
        )

    def test_057_helper_build_pem_file(self):
        """test build_pem_file with long cert (to test wrap)"""
        existing = "existing"
        cert = (
            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        )
        self.assertEqual(
            "existing-----BEGIN CERTIFICATE-----\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n-----END CERTIFICATE-----\n",
            self.build_pem_file(self.logger, existing, cert, False),
        )

    def test_058_helper_build_pem_file(self):
        """test build_pem_file for CSR"""
        existing = None
        csr = "MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A=="
        result = """-----BEGIN CERTIFICATE REQUEST-----
MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CT
ZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDg
WlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4
FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZb
eI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY
9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3
BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJh
ci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7
n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAt
iUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYu
tUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9I
NJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQs
KxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==
-----END CERTIFICATE REQUEST-----
"""
        self.assertEqual(
            result, self.build_pem_file(self.logger, existing, csr, False, True)
        )

    def test_059_helper_b64_decode(self):
        """test bas64 decoder for string value"""
        self.assertEqual("test", self.b64_decode(self.logger, "dGVzdA=="))

    def test_060_helper_b64_decode(self):
        """test bas64 decoder for byte value"""
        self.assertEqual("test", self.b64_decode(self.logger, b"dGVzdA=="))

    def test_061_helper_date_to_datestr(self):
        """convert dateobj to date-string with default format"""
        self.assertEqual(
            "2019-10-27T00:00:00Z", self.date_to_datestr(datetime.date(2019, 10, 27))
        )

    def test_062_helper_date_to_datestr(self):
        """convert dateobj to date-string with a predefined format"""
        self.assertEqual(
            "2019.10.27", self.date_to_datestr(datetime.date(2019, 10, 27), "%Y.%m.%d")
        )

    def test_063_helper_date_to_datestr(self):
        """convert dateobj to date-string for an knvalid date"""
        self.assertEqual(None, self.date_to_datestr("foo", "%Y.%m.%d"))

    def test_064_helper_datestr_to_date(self):
        """convert datestr to date with default format"""
        self.assertEqual(
            datetime.datetime(2019, 11, 27, 0, 1, 2),
            self.datestr_to_date("2019-11-27T00:01:02"),
        )

    def test_065_helper_datestr_to_date(self):
        """convert datestr to date with predefined format"""
        self.assertEqual(
            datetime.datetime(2019, 11, 27, 0, 0, 0),
            self.datestr_to_date("2019.11.27", "%Y.%m.%d"),
        )

    def test_066_helper_datestr_to_date(self):
        """convert datestr to date with invalid format"""
        self.assertEqual(None, self.datestr_to_date("foo", "%Y.%m.%d"))

    def test_067_helper_dkeys_lower(self):
        """dkeys_lower with a simple string"""
        tree = "fOo"
        self.assertEqual("fOo", self.dkeys_lower(tree))

    def test_068_helper_dkeys_lower(self):
        """dkeys_lower with a simple list"""
        tree = ["fOo", "bAr"]
        self.assertEqual(["fOo", "bAr"], self.dkeys_lower(tree))

    def test_069_helper_dkeys_lower(self):
        """dkeys_lower with a simple dictionary"""
        tree = {"kEy": "vAlUe"}
        self.assertEqual({"key": "vAlUe"}, self.dkeys_lower(tree))

    def test_070_helper_dkeys_lower(self):
        """dkeys_lower with a nested dictionary containg strings, list and dictionaries"""
        tree = {
            "kEy1": "vAlUe2",
            "keys2": ["lIsT2", {"kEyS3": "vAlUe3", "kEyS4": "vAlUe3"}],
            "keys4": {"kEyS4": "vAluE5", "kEyS5": "vAlUE6"},
        }
        self.assertEqual(
            {
                "key1": "vAlUe2",
                "keys2": ["lIsT2", {"keys3": "vAlUe3", "keys4": "vAlUe3"}],
                "keys4": {"keys5": "vAlUE6", "keys4": "vAluE5"},
            },
            self.dkeys_lower(tree),
        )

    def test_071_helper_cert_pubkey_get(self):
        """test get public_key from certificate"""
        cert = """
-----BEGIN X509 CERTIFICATE-----
MIIE2zCCAsOgAwIBAgIPAXI102H4bCWEkhD2SaLsMA0GCSqGSIb3DQEBDQUAMDIx
CzAJBgNVBAYTAkRFMQ4wDAYDVQQKEwVOb2tpYTETMBEGA1UEAwwKbmNtX3N1Yl9j
YTAeFw0yMDA1MjEwNTMyMjVaFw0yMDA2MjAyMzU5NTlaMBkxFzAVBgNVBAMTDmZv
bzEuYmFyLmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+
z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN
+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOL
hjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MF
o+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgba
j94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xo
aygpd9+UHCREhcOu/wIDAQABo4IBBTCCAQEwHwYDVR0jBBgwFoAUEZ+5Dp2l8KCZ
zHhwr3965P6xxsswHQYDVR0OBBYEFKsuSjgZZMl9vZeBB0wks4Wbg4PhMAsGA1Ud
DwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDBUBgNVHR8ETTBLMEmg
R6BFhkNodHRwOi8vc3J2Lm5jbG0tc2FtYmEubG9jYWw6ODA4MC9jcmwtYXMtZGVy
L2N1cnJlbnRjcmwtODcuY3JsP2lkPTg3MEEGCCsGAQUFBwEBBDUwMzAxBggrBgEF
BQcwAYYlaHR0cDovL3Nydi5uY2xtLXNhbWJhLmxvY2FsOjgwOTAvY2EyLzANBgkq
hkiG9w0BAQ0FAAOCAgEAgpfWOM8fWlkwSbWtgnAKnu8GNMteOckWS1gMydOhokhY
PZdkpL8uoMWRahyjhmAH85TtHdydVaQ9NNBUTsbiOqkN2jPurDdzgfUs2gAwoR05
MkHVWI1+C3lHAVlqPWYld+6Kl3lnEjy3jFSMugTuq5h79f0KxGle7W568Xg+zI3R
Ry1dRggR6W2G9L+7Ez8Y+H/8P/gjbTO1GGYoXI4ISQl3EinL/X7XpYnQ3o14uDLb
m/h+YyLfi03m8tLJQPM7soDAZx6qI/1V4H/VT1VEKBCiec8w580rIH6GSrjUkddp
wd0p74B8xwmt9zA+gBV3Js72PBy9mdcMIvYIO3otmN2jQL8PC1B8VNEmf0l8a5wq
07qftQEI82vcrLG8Dgy7R9AxrIxd1xnZOTrcOo3dU+blAehAJZWT2B0B8XyoGk2/
CiMCwOQijMgp97tjnuQ3dkRhu50kUN5LCa9jU2ongXj0+28mEKZ5rAQUBQmAMITR
hTkTB1OxdpFMxyg83OZdYu/xit9YfVB0AAyarqjTst/y79UkExfEf0sAARBiffkx
PZwtZpoz736yvIqanX6u2zUHLDzSRZXOZHY6pxANqoH6howxqGkI3FMjeDbDUln7
/TEtRju77ONV1X+8iPYrnQqTRoR3a3IwT8Cz/HErNM6aNCvPVPqakZXZrcpXILY=
-----END X509 CERTIFICATE-----"""

        pub_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3y
Ay5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97
hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIg
kikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8
Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw
/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu
/wIDAQAB
-----END PUBLIC KEY-----
"""
        self.assertEqual(pub_key, self.cert_pubkey_get(self.logger, cert))

    def test_072_helper_csr_pubkey_get(self):
        """test get public_key from certificate"""
        csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A=="""

        pub_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3y
Ay5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97
hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIg
kikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8
Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw
/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu
/wIDAQAB
-----END PUBLIC KEY-----
"""
        self.assertEqual(pub_key, self.csr_pubkey_get(self.logger, csr))

    def test_073_helper_csr_pubkey_get(self):
        """test get public_key from certificate"""
        csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A=="""

        pub_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3y
Ay5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97
hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIg
kikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8
Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw
/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu
/wIDAQAB
-----END PUBLIC KEY-----
"""
        self.assertEqual(pub_key, self.csr_pubkey_get(self.logger, csr, encoding="pem"))

    def test_074_helper_csr_pubkey_get(self):
        """test get public_key from certificate"""
        csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A=="""
        pub_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu/wIDAQAB"
        self.assertEqual(
            pub_key, self.csr_pubkey_get(self.logger, csr, encoding="base64der")
        )

    def test_075_helper_csr_pubkey_get(self):
        """test get public_key from certificate"""
        csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A=="""
        pub_key = b"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu/wIDAQAB"
        self.assertEqual(
            pub_key,
            base64.b64encode(self.csr_pubkey_get(self.logger, csr, encoding="der")),
        )

    def test_076_helper_csr_pubkey_get(self):
        """test get public_key from certificate"""
        csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A=="""
        pub_key = b"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu/wIDAQAB"
        self.assertFalse(self.csr_pubkey_get(self.logger, csr, encoding="unk"))

    def test_077_helper_convert_byte_to_string(self):
        """convert byte2string for a string value"""
        self.assertEqual("foo", self.convert_byte_to_string("foo"))

    def test_078_helper_convert_byte_to_string(self):
        """convert byte2string for a string value"""
        self.assertEqual("foo", self.convert_byte_to_string("foo"))

    def test_079_helper_convert_byte_to_string(self):
        """convert byte2string for a string value"""
        self.assertNotEqual("foo", self.convert_byte_to_string("foobar"))

    def test_080_helper_convert_byte_to_string(self):
        """convert byte2string for a string value"""
        self.assertNotEqual("foo", self.convert_byte_to_string(b"foobar"))

    def test_081_helper_b64_url_encode(self):
        """test b64_url_encode of string"""
        self.assertEqual(b"c3RyaW5n", self.b64_url_encode(self.logger, "string"))

    def test_082_helper_b64_url_encode(self):
        """test b64_url_encode of byte"""
        self.assertEqual(b"Ynl0ZQ", self.b64_url_encode(self.logger, b"byte"))

    def test_083_helper_csr_cn_get(self):
        """get cn of csr"""
        csr = "MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1rqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDaRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqYZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAl3egrkO3I94IpxxfSJmVetd7s9uW3lSBqh9OiypFevQO7ZgUxau+k05NKTUNpSq3W9H/lRr5AG5x3/VX8XZVbcLKXQ0d6e38uXBAUFQQJmjBVYqd8KcMfqLeFFUBsLcG04yek2tNIbhXZfBtw9UYO27Y5ktMgWjAz2VskIXl3E2L0b8tGnSKDoMB07IVpYB9bHfHX4o+ccIgq1HxyYT1d+eVIQuSHHxR7j7Wkgb8RG9bCWpVWaYWKWU0Inh3gMnP06kPBJ9nOB4adgC3Hz37ab/0KpmBuQBEgmMfINwV/OpJVv2Su1FYK+uX7E1qUGae6QDsfg0Yor9uP0Vkv4b1NA=="
        self.assertEqual("foo1.bar.local", self.csr_cn_get(self.logger, csr))

    def test_084_helper_csr_cn_get(self):
        """get cn of csr"""
        csr = b"MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1rqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDaRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqYZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAl3egrkO3I94IpxxfSJmVetd7s9uW3lSBqh9OiypFevQO7ZgUxau+k05NKTUNpSq3W9H/lRr5AG5x3/VX8XZVbcLKXQ0d6e38uXBAUFQQJmjBVYqd8KcMfqLeFFUBsLcG04yek2tNIbhXZfBtw9UYO27Y5ktMgWjAz2VskIXl3E2L0b8tGnSKDoMB07IVpYB9bHfHX4o+ccIgq1HxyYT1d+eVIQuSHHxR7j7Wkgb8RG9bCWpVWaYWKWU0Inh3gMnP06kPBJ9nOB4adgC3Hz37ab/0KpmBuQBEgmMfINwV/OpJVv2Su1FYK+uX7E1qUGae6QDsfg0Yor9uP0Vkv4b1NA=="
        self.assertEqual("foo1.bar.local", self.csr_cn_get(self.logger, csr))

    def test_085_helper_convert_string_to_byte(self):
        """convert string value to byte"""
        value = "foo.bar"
        self.assertEqual(b"foo.bar", self.convert_string_to_byte(value))

    def test_086_helper_convert_string_to_byte(self):
        """convert string value to byte"""
        value = b"foo.bar"
        self.assertEqual(b"foo.bar", self.convert_string_to_byte(value))

    def test_087_helper_convert_string_to_byte(self):
        """convert string value to byte"""
        value = b""
        self.assertEqual(b"", self.convert_string_to_byte(value))

    def test_088_helper_convert_string_to_byte(self):
        """convert string value to byte"""
        value = ""
        self.assertEqual(b"", self.convert_string_to_byte(value))

    def test_089_helper_convert_string_to_byte(self):
        """convert string value to byte"""
        value = None
        self.assertFalse(self.convert_string_to_byte(value))

    def test_090_helper_get_url(self):
        """get_url https"""
        data_dic = {
            "HTTP_HOST": "http_host",
            "SERVER_PORT": "443",
            "PATH_INFO": "path_info",
        }
        self.assertEqual("https://http_host", self.get_url(data_dic, False))

    def test_091_helper_get_url(self):
        """get_url http"""
        data_dic = {
            "HTTP_HOST": "http_host",
            "SERVER_PORT": "80",
            "PATH_INFO": "path_info",
        }
        self.assertEqual("http://http_host", self.get_url(data_dic, False))

    def test_092_helper_get_url(self):
        """get_url http wsgi.scheme"""
        data_dic = {
            "HTTP_HOST": "http_host",
            "SERVER_PORT": "80",
            "PATH_INFO": "path_info",
            "wsgi.url_scheme": "wsgi.url_scheme",
        }
        self.assertEqual("wsgi.url_scheme://http_host", self.get_url(data_dic, False))

    def test_093_helper_get_url(self):
        """get_url https include_path true bot no pathinfo"""
        data_dic = {"HTTP_HOST": "http_host", "SERVER_PORT": "443"}
        self.assertEqual("https://http_host", self.get_url(data_dic, True))

    def test_094_helper_get_url(self):
        """get_url https and path info"""
        data_dic = {
            "HTTP_HOST": "http_host",
            "SERVER_PORT": "443",
            "PATH_INFO": "path_info",
        }
        self.assertEqual("https://http_hostpath_info", self.get_url(data_dic, True))

    def test_095_helper_get_url(self):
        """get_url wsgi.url and pathinfo"""
        data_dic = {
            "HTTP_HOST": "http_host",
            "SERVER_PORT": "80",
            "PATH_INFO": "path_info",
            "wsgi.url_scheme": "wsgi.url_scheme",
        }
        self.assertEqual(
            "wsgi.url_scheme://http_hostpath_info", self.get_url(data_dic, True)
        )

    def test_096_helper_get_url(self):
        """get_url http and pathinfo"""
        data_dic = {
            "HTTP_HOST": "http_host",
            "SERVER_PORT": "80",
            "PATH_INFO": "path_info",
        }
        self.assertEqual("http://http_hostpath_info", self.get_url(data_dic, True))

    def test_097_helper_get_url(self):
        """get_url without hostinfo"""
        data_dic = {"SERVER_PORT": "80", "PATH_INFO": "path_info"}
        self.assertEqual("http://localhost", self.get_url(data_dic, False))

    def test_098_helper_get_url(self):
        """get_url without SERVER_PORT"""
        data_dic = {"HTTP_HOST": "http_host"}
        self.assertEqual("http://http_host", self.get_url(data_dic, True))

    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_099_helper_url_get(self, mock_request):
        """successful url get without dns servers"""
        mock_request.return_value.text = "foo"
        mock_request.return_value.status_code = 200
        result, status_code, error_msg = self.url_get(self.logger, "url")
        self.assertEqual("foo", result)
        self.assertEqual(200, status_code)
        self.assertEqual(None, error_msg)

    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_100_helper_url_get(self, mock_request):
        """successful url get without dns servers"""
        mock_request.return_value.text = "foo"
        mock_request.return_value.status_code = 200
        result, status_code, error_msg = self.url_get(
            self.logger, "url", "dns", "proxy"
        )
        self.assertEqual("foo", result)
        self.assertEqual(200, status_code)
        self.assertEqual(None, error_msg)

    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_101_helper_url_get(self, mock_request):
        """unsuccessful url get without dns servers"""
        # this is stupid but triggrs an expeption
        mock_request.return_value = {"foo": "foo"}
        result, status_code, error_msg = self.url_get(self.logger, "url")
        self.assertEqual(None, result)
        self.assertEqual(500, status_code)
        self.assertIn("Could not fetch URL", error_msg)

    @patch("acme2certifier.acme_srv.helpers.network.url_get_with_own_dns")
    def test_102_helper_url_get(self, mock_request):
        """successful url get with dns servers"""
        mock_request.return_value = ("foo", 200, None)
        result, status_code, error_msg = self.url_get(self.logger, "url", "dns")
        self.assertEqual("foo", result)
        self.assertEqual(200, status_code)
        self.assertEqual(None, error_msg)

    @patch(
        "acme2certifier.acme_srv.helpers.network.requests.get",
        side_effect=Mock(side_effect=Exception("foo")),
    )
    def test_103_helper_url_get(self, mock_request):
        """unsuccessful url_get"""
        # mock_request.return_value.text = 'foo'
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            result, status_code, error_msg = self.url_get(self.logger, "url")
            self.assertEqual(None, result)
            self.assertEqual(500, status_code)
            self.assertIn("Could not fetch URL", error_msg)
        self.assertIn("ERROR:test_a2c:foo", lcm.output)

    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_104_helper_url_get(self, mock_request):
        """unsuccessful url_get fallback to v4"""
        object = Mock()
        object.text = "foo"
        object.status_code = 200
        mock_request.side_effect = [Exception("foo"), object]
        result, status_code, error_msg = self.url_get(self.logger, "url")
        self.assertEqual("foo", result)
        self.assertEqual(200, status_code)
        self.assertEqual(None, error_msg)

    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_105_helper_url_get_with_own_dns(self, mock_request):
        """successful url_get_with_own_dns get with dns servers"""
        mock_request.return_value.text = "foo"
        mock_request.return_value.status_code = 200
        result, status_code, error_msg = self.url_get_with_own_dns(self.logger, "url")
        self.assertEqual("foo", result)
        self.assertEqual(200, status_code)
        self.assertEqual(None, error_msg)

    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_106_helper_url_get_with_own_dns(self, mock_request):
        """successful url_get_with_own_dns get with dns servers"""
        mock_request.return_value = {"foo": "foo"}
        result, status_code, error_msg = self.url_get_with_own_dns(self.logger, "url")
        self.assertEqual(None, result)
        self.assertEqual(500, status_code)
        self.assertIn(
            "Could not get URL by using the configured DNS servers", error_msg
        )

    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_107_helper_url_get_with_own_dns_non_200(self, mock_request):
        """url_get_with_own_dns with non-200 status code"""
        mock_request.return_value.text = "Not Found"
        mock_request.return_value.status_code = 404
        mock_request.return_value.reason = "Not Found"
        result, status_code, error_msg = self.url_get_with_own_dns(
            self.logger, "http://example.com/test"
        )
        self.assertEqual("Not Found", result)
        self.assertEqual(404, status_code)
        self.assertEqual("http://example.com/test Not Found", error_msg)

    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_108_helper_url_get_with_own_dns_verify_false(self, mock_request):
        """url_get_with_own_dns with verify=False parameter"""
        mock_request.return_value.text = "secure content"
        mock_request.return_value.status_code = 200
        result, status_code, error_msg = self.url_get_with_own_dns(
            self.logger, "https://secure.example.com", verify=False
        )
        self.assertEqual("secure content", result)
        self.assertEqual(200, status_code)
        self.assertEqual(None, error_msg)
        # Verify that requests.get was called with verify=False
        mock_request.assert_called_once()
        call_args = mock_request.call_args
        self.assertEqual(call_args[1]["verify"], False)

    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_109_helper_url_get_with_own_dns_connection_cleanup(self, mock_request):
        """url_get_with_own_dns ensures connection cleanup after exception"""
        mock_request.side_effect = requests.exceptions.ConnectionError(
            "Connection failed"
        )

        # Store original connection function
        from acme2certifier.acme_srv.helpers.network import connection

        original_create_connection = connection.create_connection

        result, status_code, error_msg = self.url_get_with_own_dns(
            self.logger, "http://example.com"
        )

        # Verify exception handling
        self.assertEqual(None, result)
        self.assertEqual(500, status_code)
        self.assertIn(
            "Could not get URL by using the configured DNS servers", error_msg
        )

        # Verify connection was restored after exception
        self.assertEqual(connection.create_connection, original_create_connection)

    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_110_helper_url_get_with_own_dns_server_error(self, mock_request):
        """url_get_with_own_dns with server error status code"""
        mock_request.return_value.text = "Internal Server Error"
        mock_request.return_value.status_code = 500
        mock_request.return_value.reason = "Internal Server Error"
        result, status_code, error_msg = self.url_get_with_own_dns(
            self.logger, "http://api.example.com/endpoint"
        )
        self.assertEqual("Internal Server Error", result)
        self.assertEqual(500, status_code)
        self.assertEqual(
            "http://api.example.com/endpoint Internal Server Error", error_msg
        )

    @patch("acme2certifier.acme_srv.helpers.network.load_config")
    def test_111_helper_dns_server_list_load(self, mock_load_config):
        """successful dns_server_list_load with empty config file"""
        mock_load_config.return_value = {}
        self.assertEqual(["9.9.9.9", "8.8.8.8"], self.dns_server_list_load())

    @patch("acme2certifier.acme_srv.helpers.network.load_config")
    def test_112_helper_dns_server_list_load(self, mock_load_config):
        """successful dns_server_list_load with empty Challenge section"""
        mock_load_config.return_value = {"Challenge": {}}
        self.assertEqual(["9.9.9.9", "8.8.8.8"], self.dns_server_list_load())

    @patch("acme2certifier.acme_srv.helpers.network.load_config")
    def test_113_helper_dns_server_list_load(self, mock_load_config):
        """successful dns_server_list_load with wrong Challenge section"""
        mock_load_config.return_value = {"Challenge": {"foo": "bar"}}
        self.assertEqual(["9.9.9.9", "8.8.8.8"], self.dns_server_list_load())

    @patch("acme2certifier.acme_srv.helpers.network.load_config")
    def test_114_helper_dns_server_list_load(self, mock_load_config):
        """successful dns_server_list_load with wrong json format"""
        mock_load_config.return_value = {"Challenge": {"dns_server_list": "bar"}}
        self.assertEqual(["9.9.9.9", "8.8.8.8"], self.dns_server_list_load())

    @patch("acme2certifier.acme_srv.helpers.network.load_config")
    def test_115_helper_dns_server_list_load(self, mock_load_config):
        """successful dns_server_list_load with wrong json format"""
        mock_load_config.return_value = {
            "Challenge": {"dns_server_list": '["foo", "bar"]'}
        }
        self.assertEqual(["foo", "bar"], self.dns_server_list_load())

    def test_116_helper_config_dns_server_list_load_defaults(self):
        """config_dns_server_list_load returns defaults when no settings are present."""
        config_dic = {}

        dns_server_list, dns_validation_pause_timer = self.config_dns_server_list_load(
            self.logger, config_dic
        )

        self.assertEqual([], dns_server_list)
        self.assertEqual(0.5, dns_validation_pause_timer)

    def test_117_helper_config_dns_server_list_load_default_section(self):
        """config_dns_server_list_load loads dns_server_list from DEFAULT section."""
        config_dic = {"DEFAULT": {"dns_server_list": '["1.1.1.1", "8.8.8.8"]'}}

        dns_server_list, dns_validation_pause_timer = self.config_dns_server_list_load(
            self.logger, config_dic
        )

        self.assertEqual(["1.1.1.1", "8.8.8.8"], dns_server_list)
        self.assertEqual(0.5, dns_validation_pause_timer)

    def test_118_helper_config_dns_server_list_load_default_section_parse_error(self):
        """config_dns_server_list_load logs warning on invalid DEFAULT dns_server_list."""
        config_dic = {"DEFAULT": {"dns_server_list": "not-json"}}

        with self.assertLogs("test_a2c", level="DEBUG") as log_context:
            dns_server_list, dns_validation_pause_timer = (
                self.config_dns_server_list_load(self.logger, config_dic)
            )

        self.assertEqual([], dns_server_list)
        self.assertEqual(0.5, dns_validation_pause_timer)
        self.assertTrue(
            any(
                "Failed to load dns_server_list from configuration" in record.message
                for record in log_context.records
                if record.levelname == "WARNING"
            )
        )

    def test_119_helper_config_dns_server_list_load_challenge_section_and_timer(self):
        """config_dns_server_list_load handles deprecated Challenge section and timer."""
        config_dic = {
            "Challenge": {
                "dns_server_list": '["9.9.9.9"]',
                "dns_validation_pause_timer": "7",
            }
        }

        with self.assertLogs("test_a2c", level="DEBUG") as log_context:
            dns_server_list, dns_validation_pause_timer = (
                self.config_dns_server_list_load(self.logger, config_dic)
            )

        self.assertEqual(["9.9.9.9"], dns_server_list)
        self.assertEqual(7, dns_validation_pause_timer)
        self.assertTrue(
            any(
                "dns_server_list parameter found in Challenge section - this is deprecated"
                in record.message
                for record in log_context.records
                if record.levelname == "WARNING"
            )
        )

    def test_120_helper_config_dns_server_list_load_challenge_section_parse_errors(
        self,
    ):
        """config_dns_server_list_load logs warnings on invalid Challenge values."""
        config_dic = {
            "Challenge": {
                "dns_server_list": "bad-json",
                "dns_validation_pause_timer": "NaN",
            }
        }

        with self.assertLogs("test_a2c", level="DEBUG") as log_context:
            dns_server_list, dns_validation_pause_timer = (
                self.config_dns_server_list_load(self.logger, config_dic)
            )

        self.assertEqual([], dns_server_list)
        self.assertEqual(0.5, dns_validation_pause_timer)
        self.assertTrue(
            any(
                "Failed to load dns_server_list from configuration" in record.message
                for record in log_context.records
                if record.levelname == "WARNING"
            )
        )
        self.assertTrue(
            any(
                "Failed to parse dns_validation_pause_timer from configuration"
                in record.message
                for record in log_context.records
                if record.levelname == "WARNING"
            )
        )

    def test_121_helper_csr_san_get(self):
        """get sans but no csr"""
        csr = None
        self.assertEqual([], self.csr_san_get(self.logger, csr))

    def test_122_helper_csr_san_get(self):
        """get sans but one san with =="""
        csr = "MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEANAXOIkv0CovmdzyoAv1dsiK0TK2XHBdBTEPFDsrT7MnrIXOFS4FnDrg8zpn7QBzBRTl3HaKN8fnpIHkA/6ZRDqaEJq0AeskjxIg9LKDBBx5TEdgPh1CwruRWLlXtrqU7XXQmk0wLIo/kfaDRcTjyJ3yHTEK06mCAaws0sTKlTw2D4pIiDRp8zbLHeSEUX5UKOSGbLSSUY/F2XwgPB8nC2BCD/gkvHRR+dMQSdOCiS9GLwZdYAAyESw6WhmGPjmVbeTRgSt/9//yx3JKQgkFYmpSMLKR2G525M+l1qfku/4b0iMOa4vQjFRj5AXZH0SBpAKtvnFxUpP6P9mTE7+akOQ=="
        self.assertEqual(["DNS:foo1.bar.local"], self.csr_san_get(self.logger, csr))

    def test_123_helper_csr_san_get(self):
        """get sans but one san without =="""
        csr = "MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEANAXOIkv0CovmdzyoAv1dsiK0TK2XHBdBTEPFDsrT7MnrIXOFS4FnDrg8zpn7QBzBRTl3HaKN8fnpIHkA/6ZRDqaEJq0AeskjxIg9LKDBBx5TEdgPh1CwruRWLlXtrqU7XXQmk0wLIo/kfaDRcTjyJ3yHTEK06mCAaws0sTKlTw2D4pIiDRp8zbLHeSEUX5UKOSGbLSSUY/F2XwgPB8nC2BCD/gkvHRR+dMQSdOCiS9GLwZdYAAyESw6WhmGPjmVbeTRgSt/9//yx3JKQgkFYmpSMLKR2G525M+l1qfku/4b0iMOa4vQjFRj5AXZH0SBpAKtvnFxUpP6P9mTE7+akOQ"
        self.assertEqual(["DNS:foo1.bar.local"], self.csr_san_get(self.logger, csr))

    def test_124_helper_csr_san_get(self):
        """get sans but two sans"""
        csr = "MIICpzCCAY8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgSTBHBgkqhkiG9w0BCQ4xOjA4MAsGA1UdDwQEAwIF4DApBgNVHREEIjAggg5mb28xLmJhci5sb2NhbIIOZm9vMi5iYXIubG9jYWwwDQYJKoZIhvcNAQELBQADggEBADeuf4J8Xziw2OuvLNnLOSgHQl2HdMFtRdgJoun7zPobsP3L3qyXLvvhJcQsIJggu5ZepnHGrCxroSbtRSO65GtLQA0Rq3DCGcPIC1fe9AYrqoynx8bWt2Hd+PyDrBppHVoQzj6yNCt6XNSDs04BMtjs9Pu4DD6DDHmxFMVNdHXea2Rms7C5nLQvXgw7yOF3Zk1vEu7Kue7d3zZMhN+HwwrNEA7RGAEzHHlCv5LL4Mw+kf6OJ8nf/WDiLDKEQIh6bnOuB42Y2wUMpzui8Uur0VJO+twY46MvjiVMMBZE3aPJU33eNPAQVC7GinStn+zQIJA5AADdcO8Lk1qdtaDiGp8"
        self.assertEqual(
            ["DNS:foo1.bar.local", "DNS:foo2.bar.local"],
            self.csr_san_get(self.logger, csr),
        )

    def test_125_helper_csr_san_get(self):
        """get sans but three sans"""
        csr = "MIICtzCCAZ8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgWTBXBgkqhkiG9w0BCQ4xSjBIMAsGA1UdDwQEAwIF4DA5BgNVHREEMjAwgg5mb28xLmJhci5sb2NhbIIOZm9vMi5iYXIubG9jYWyCDmZvbzMuYmFyLmxvY2FsMA0GCSqGSIb3DQEBCwUAA4IBAQAQRkub6G4uijaXOYpCkoz40I+SVRsbRDgnMNjsooZz1+7DVglFjrr6Pb0PPTOvOxtmbHP2KK0WokDn4LqOD2t0heuI+KPQy7m/ROpOB/YZOzTWEB8yS4vjkf/RFiJ7fnCAc8vA+3K/mBVb+89F8w/KlyPmpg1GK7UNgjEa5bnznTox8q12CocCJVykPEiC8AT/VPWUOPfg6gs+V6LO8R73VRPMVy0ttYKGX80ob+KczDTMUhoxXg8OG+G+bXXU+4Tu4l+nQWf2lFejECi/vNKzUT90IbcGJwyk7rc4Q7BJ/t/5nMo+vuV9f+2HI7qakHcw6u9RGylL4OYDf1CrqF1R"
        self.assertEqual(
            ["DNS:foo1.bar.local", "DNS:foo2.bar.local", "DNS:foo3.bar.local"],
            self.csr_san_get(self.logger, csr),
        )

    def test_126_helper_csr_san_get(self):
        """get sans but three sans"""
        csr = "MIIBFjCBvQIBADAYMRYwFAYDVQQDEw1mb28uYmFyLmxvY2FsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETOQukalTTCD8y7zoAsmxeAWlbi9oZtzh7XQc7A7KF4fZLP3pYjoZG6s+sXCp7bUpKhuIejrDRp1cFE5NlEK8jaBDMEEGCSqGSIb3DQEJDjE0MDIwMAYDVR0RBCkwJ4INZm9vLmJhci5sb2NhbIcEwKgOg4cQ/oAAAAAAAAACFV3//sABAjAKBggqhkjOPQQDAgNIADBFAiBKUb5r/8aSN4/utaDoi0vIcaASVZz8p1nSJ1YWSCkIpAIhAI20iVBu5j0tBmTc3uRzKIYTqsnXpH0UV8bcONy4m1Sa"
        self.assertEqual(
            ["DNS:foo.bar.local", "IP:192.168.14.131", "IP:fe80::215:5dff:fec0:102"],
            self.csr_san_get(self.logger, csr),
        )

    def test_127_helper_csr_san_byte_get(self):
        """get sans but two sans"""
        csr = "MIICpzCCAY8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgSTBHBgkqhkiG9w0BCQ4xOjA4MAsGA1UdDwQEAwIF4DApBgNVHREEIjAggg5mb28xLmJhci5sb2NhbIIOZm9vMi5iYXIubG9jYWwwDQYJKoZIhvcNAQELBQADggEBADeuf4J8Xziw2OuvLNnLOSgHQl2HdMFtRdgJoun7zPobsP3L3qyXLvvhJcQsIJggu5ZepnHGrCxroSbtRSO65GtLQA0Rq3DCGcPIC1fe9AYrqoynx8bWt2Hd+PyDrBppHVoQzj6yNCt6XNSDs04BMtjs9Pu4DD6DDHmxFMVNdHXea2Rms7C5nLQvXgw7yOF3Zk1vEu7Kue7d3zZMhN+HwwrNEA7RGAEzHHlCv5LL4Mw+kf6OJ8nf/WDiLDKEQIh6bnOuB42Y2wUMpzui8Uur0VJO+twY46MvjiVMMBZE3aPJU33eNPAQVC7GinStn+zQIJA5AADdcO8Lk1qdtaDiGp8"
        self.assertEqual(
            "MCCCDmZvbzEuYmFyLmxvY2Fsgg5mb28yLmJhci5sb2NhbA==",
            self.csr_san_byte_get(self.logger, csr),
        )

    @patch("acme2certifier.acme_srv.helpers.csr.csr_load")
    def test_128_helper_csr_san_get(self, mock_csrload):
        """get sans but three sans"""
        csr = "csr"
        mock_csrload.return_value = "mock_csrload"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual([], self.csr_san_get(self.logger, csr))
        self.assertIn(
            "ERROR:test_a2c:Error while getting SANs from CSR: 'str' object has no attribute 'extensions'",
            lcm.output,
        )

    def test_129_helper_csr_extensions_get(self):
        """get sns in hex"""
        csr = "MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEANAXOIkv0CovmdzyoAv1dsiK0TK2XHBdBTEPFDsrT7MnrIXOFS4FnDrg8zpn7QBzBRTl3HaKN8fnpIHkA/6ZRDqaEJq0AeskjxIg9LKDBBx5TEdgPh1CwruRWLlXtrqU7XXQmk0wLIo/kfaDRcTjyJ3yHTEK06mCAaws0sTKlTw2D4pIiDRp8zbLHeSEUX5UKOSGbLSSUY/F2XwgPB8nC2BCD/gkvHRR+dMQSdOCiS9GLwZdYAAyESw6WhmGPjmVbeTRgSt/9//yx3JKQgkFYmpSMLKR2G525M+l1qfku/4b0iMOa4vQjFRj5AXZH0SBpAKtvnFxUpP6P9mTE7+akOQ"
        self.assertEqual(
            ["AwIF4A==", "MBCCDmZvbzEuYmFyLmxvY2Fs"],
            self.csr_extensions_get(self.logger, csr),
        )

    def test_130_helper_csr_extensions_get(self):
        """get tnauth identifier"""
        csr = "MIICuzCCAaMCAQAwHjEcMBoGA1UEAwwTY2VydC5zdGlyLmJhci5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsLm4zgkl2lEx2EHy1ENfh3cYB79Xb5sD3ehkY+1pXphIWoM9KYVqHKOurModjsh75YjRBSilRfTFSk6kCUahTJyeCbM6Vzl75CcZy7poUxiK+u80JMU/xymUsrqY4GZlh2/XtFMxXHUSf3bhKZAIjBNugsvR/sHtEvJ6RJiuYqHMWUzZ/Vby5L0ywNl+LPSY7AVTUAZ0lKrnUCP4dHnbjwjf+nPi7vT6G0yrEg0qPOYXtJOXdf7vvjLi8J+ap758NtG2qapLdbToIPr0uOEvMO6zs8z1bIyjOHU3kzlpKHzDsPYy8txxKC/3Rae7sKB9gWm8WUxFBmuA7gaFDGQAECAwEAAaBYMFYGCSqGSIb3DQEJDjFJMEcwCwYDVR0PBAQDAgXgMB4GA1UdEQQXMBWCE2NlcnQuc3Rpci5iYXIubG9jYWwwGAYIKwYBBQUHARoEDDAKoAgWBjEyMzQ1NjANBgkqhkiG9w0BAQsFAAOCAQEAjyhJfgb/zJBMYp6ylRtEXgtBpsX9ePUL/iLgIDMcGtwaFm3pkQOSBr4xiTxftnqN77SlC8UEu7PDR73JX6iqLNJWucPlhAXVrr367ygO8GGLrtGddClZmo0lhRBRErgpagWB/jFkbL8afPGJwgQQXF0KWFMcajAPiIl1l6M0w11KqJ23Pwrmi7VJHzIgh4ys0D2UrX7KuV4PIOOmG0s7jTfBSB+yUH2zwVzOAzbr3wrD1WubD7hRaHDUi4bn4DRbquQOzbqfTI6QhetUcNpq4DwhBRcnZwUMJUIcxLAsFnDgGSW+dmJe6JH8MsS+8ZmOLllyQxWzYEVquQQvxFVTZA"
        self.assertEqual(
            ["AwIF4A==", "MBWCE2NlcnQuc3Rpci5iYXIubG9jYWw=", "MAqgCBYGMTIzNDU2"],
            self.csr_extensions_get(self.logger, csr),
        )

    def test_131_helper_validate_email(self):
        """validate email containing "-" in domain"""
        self.assertTrue(self.validate_email(self.logger, "foo@example-example.com"))

    def test_132_helper_validate_email(self):
        """validate email containing "-" in user"""
        self.assertTrue(self.validate_email(self.logger, "foo-foo@example.com"))

    def test_133_helper_get_url(self):
        """get_url with xforwarded https"""
        data_dic = {
            "HTTP_X_FORWARDED_PROTO": "https",
            "HTTP_HOST": "http_host",
            "SERVER_PORT": "443",
            "PATH_INFO": "path_info",
        }
        self.assertEqual("https://http_host", self.get_url(data_dic, False))

    def test_134_helper_get_url(self):
        """get_url with xforwarded http"""
        data_dic = {
            "HTTP_X_FORWARDED_PROTO": "http",
            "HTTP_HOST": "http_host",
            "SERVER_PORT": "443",
            "PATH_INFO": "path_info",
        }
        self.assertEqual("http://http_host", self.get_url(data_dic, False))

    def test_135_helper_validate_email(self):
        """validate email containing first letter of domain cannot be a number"""
        self.assertFalse(self.validate_email(self.logger, "foo@1example.com"))

    def test_136_helper_validate_email(self):
        """validate email containing last letter of domain cannot -"""
        self.assertFalse(self.validate_email(self.logger, "foo@example-.com"))

    def test_136b_helper_validate_email_double_dot(self):
        """validate email rejecting consecutive dots in domain"""
        self.assertFalse(self.validate_email(self.logger, "foo@example..com"))

    def test_136c_helper_validate_email_multi_tld(self):
        """validate email with multi-label TLD"""
        self.assertTrue(self.validate_email(self.logger, "foo@example.co.uk"))

    def test_137_helper_cert_dates_get(self):
        """get issuing and expiration date from rsa certificate"""
        cert = "MIIElTCCAn2gAwIBAgIRAKD_ulfqPUn-ggOUHOxjp40wDQYJKoZIhvcNAQELBQAwSDELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEXMBUGA1UECgwOQWNtZTJDZXJ0aWZpZXIxDzANBgNVBAMMBnN1Yi1jYTAeFw0yMDA1MjcxMjMwMjNaFw0yMDA2MjYxMjMwMjNaMBkxFzAVBgNVBAMMDmZvbzEuYmFyLmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx-z-9wsEewBf1hnk3yAy5TFg-lWVdwk2QRdAMDTExVP823QF_K-t6cxJV_-QuWVbHN-lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X-gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ-BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo-tLu0toAc0nm9v8Otme28_kpJxmW3iOMkqN9BE-qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw_a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD_Xoaygpd9-UHCREhcOu_wIDAQABo4GoMIGlMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDAdBgNVHQ4EFgQUqy5KOBlkyX29l4EHTCSzhZuDg-EwDgYDVR0PAQH_BAQDAgWgMB8GA1UdIwQYMBaAFBs0P896R0FUZHfnxMJL52ftKQOkMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQB7pQpILzxqcU2RKlr17rcne6NSJTUJnNXALeUFy5PrnjjJY1_B1cKaWluk3p7AMFvUjBpcucGCfEDudW290AQxYjrvl8_ePkzRzEkAo76L7ZqED5upYBZVn_3lA5Alr8L67UC0bDMhKTsy8WJzhWHQlMb37_YFUvtNPoI_MI09Q842VXeNQz5UDZmW9qhyeDIkf6fwOAO66VnGTLuUm2LGQZ-St2GauxR0ZUcRtMJoc-c7WOdHs8DlUCoFtglrzVH98501Sx749CG4nkJr4QNDpkw2hAhlo4Cxzp6PlljPNSgM9MsqqVdrgqDteDM_n-yrVFGezCik4QexDkWARPutRLQtpbhudExVnoFM68ihZ0y3oeDjgUBLybBQpcBAsBqiJ66Q8HTZRSqO9zlKW5Vm1KwAVDh_qgELxvqd0wIVkyxBKPta2l1fvb5YBiVqo4JyNcCTnoBS1emO4vk8XjroKijwLnU0cEXwHrY4JF1uU_kOtoZMGPul5EuBMcODLs7JJ3_IqJd8quI7Vf5zSsaB6nSzQ8XmiQiVogKflBeLl7AWmYCiL-FLP_q4dSJmvdr6fPMNy4-cfDO4Awc8RNfv-VjF5Mq57X1IXJrWKkat4lCEoPMq5WRJV8uVm6XNdwvUJxgCYR9mfol7T6imODDd7BNV4dKYvyteoS0auC0iww"
        self.assertEqual(
            (1590582623, 1593174623), self.cert_dates_get(self.logger, cert)
        )

    def test_138_helper_cert_dates_get(self):
        """get issuing and expiration date no certificate"""
        cert = None
        self.assertEqual((0, 0), self.cert_dates_get(self.logger, cert))

    def test_139_helper_cert_dates_get(self):
        """get issuing and expiration date damaged certificate"""
        cert = "foo"
        self.assertEqual((0, 0), self.cert_dates_get(self.logger, cert))

    def test_140_helper_cert_dates_get(self):
        """get issuing and expiration date ecc certificate"""
        cert = "MIIDozCCAYugAwIBAgIIMMxkE7mRR+YwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMDA3MTEwNDUzMTFaFw0yMTA3MTEwNDUzMTFaMBkxFzAVBgNVBAMMDmZvbzEuYmFyLmxvY2FsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER/KMoV5+zQgegqYue2ztPK2nZVpK2vxb02UzwyHw4ebhJ2gBobI23lSBRa1so1ug0kej7U+ohm5aGFdNxLM0G6OBqDCBpTALBgNVHQ8EBAMCBeAwGQYDVR0RBBIwEIIOZm9vMS5iYXIubG9jYWwwHQYDVR0OBBYEFCSaU743wU8jMETIO381r13tVLdMMA4GA1UdDwEB/wQEAwIFoDAfBgNVHSMEGDAWgBS/3o6OBiIiq61DyN3UT6irSEE+1TAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEAmmhHuBhXNM2Azv53rCKY72yTQIoDVHjYrAvTmS6NsJzYflEOMkI7FCes64dWp54BerSD736Yax67b4XmLXc/+T41d7QAcnhY5xvLJiMpSsW37icHcLZpjlOrYDoRmny2U7n6t1aQ03nwgV+BgdaUQYLkUZuczs4kdqH1c9Ot9CCRTHpqSWlmWzGeRgt2uT4gKhFESP9lzx37YwKBHulBGthv1kcAaz8w8iPXBg01OEDiraXCBZFoYDEpDi2w2Y6ChCr7sNsY7aJ3a+2iHGYlktXEntk78S+g00HW61G9oLoRgeqEH3L6qVIpnswPAU/joub0YhNBIUFenCj8c3HMBgMcczzdZL+qStdymhpVkZetzXtMTKtgmxhkRzAOQUBBcHFc+wM97FqC0S4HJAuoHQ4EJ46MxwZH0jBVqcqCPMSaJ88uV902+VGGXrnxMR8RbGWLoCmsYb1ISmBUt+31PjMCYbXKwLmzvbRpO7XAQimvtOqoufl5yeRUJRLcUS6Let0QzU196/nZ789d7Etep7RjDYQm7/QhiWH197yKZ5/mUxqfyHDQ3hk5iX7S/gbo1jQXElEv5tB8Ozs+zVQmB2bXpN8c+8XUaZnwvYC2y+0LAQN4z7xilReCaasxQSsEOLCrlsannkGV704HYnnaKBS2tI948QotHnADHdfHl3o"
        self.assertEqual(
            (1594443191, 1625979191), self.cert_dates_get(self.logger, cert)
        )

    @patch("acme2certifier.acme_srv.helpers.certificates.date_to_uts_utc")
    @patch("acme2certifier.acme_srv.helpers.certificates.cert_load")
    def test_141_helper_cert_dates_get(self, mock_cert, mock_dates):
        """get issuing and expiration date excaption"""
        mock_dates.side_effect = [Exception("not_valid_before_utc"), 123, 456]
        mock_cert = Mock()
        mock_cert.not_valid_before_utc.side_effect = Exception("not_valid_before_utc")
        mock_cert.not_valid_after_utc.side_effect = Exception("not_valid_after_utc")
        with self.assertLogs("test_a2c", level="DEBUG") as lcm:
            self.assertEqual((123, 456), self.cert_dates_get(self.logger, "cert"))
        self.assertIn(
            "DEBUG:test_a2c:Error while getting dates from certificate. Fallback to deprecated method: not_valid_before_utc",
            lcm.output,
        )

    @patch("acme2certifier.acme_srv.helpers.certificates.date_to_uts_utc")
    @patch("acme2certifier.acme_srv.helpers.certificates.cert_load")
    def test_142_helper_cert_dates_get(self, mock_cert, mock_dates):
        """get issuing and expiration date excaption"""
        mock_dates.side_effect = [Exception("uts")]
        mock_cert = Mock()
        mock_cert.not_valid_before_utc.side_effect = Exception("not_valid_before_utc")
        mock_cert.not_valid_after_utc.side_effect = Exception("not_valid_after_utc")
        with self.assertLogs("test_a2c", level="DEBUG") as lcm:
            self.assertEqual((0, 0), self.cert_dates_get(self.logger, "cert"))
        self.assertIn(
            "DEBUG:test_a2c:Error while getting dates from certificate. Fallback to deprecated method: uts",
            lcm.output,
        )
        self.assertIn(
            "ERROR:test_a2c:Error while getting dates from certificate: uts", lcm.output
        )

    @patch("dns.resolver.Resolver")
    def test_143_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning covering github"""
        mock_resolve.return_value.query.return_value = ["foo"]
        self.assertEqual(
            (None, False, None),
            self.fqdn_resolve(self.logger, "foo", dnssrv="10.0.0.1"),
        )

    @patch("dns.resolver.Resolver")
    def test_144_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning covering github"""
        mock_resolve.return_value.resolve.return_value = ["foo"]
        self.assertEqual(
            ("foo", False, None),
            self.fqdn_resolve(self.logger, "foo.bar.local", dnssrv="10.0.0.1"),
        )

    @patch("dns.resolver.Resolver")
    def test_145_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning a single entry and catch_single"""
        mock_resolve.return_value.resolve.return_value = ["foo"]
        self.assertEqual((None, False, None), self.fqdn_resolve(self.logger, "foo"))

    @patch("dns.resolver.Resolver")
    def test_146_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning two entries but catch singles"""
        mock_resolve.return_value.resolve.side_effect = [["v41", "v42"], ["v61", "v62"]]
        self.assertEqual(
            ("v41", False, None),
            self.fqdn_resolve(self.logger, "foo.bar.local", dnssrv="10.0.0.1"),
        )

    @patch("dns.resolver.Resolver")
    def test_147_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning only ipv6 and catchsingle"""
        mock_resolve.return_value.resolve.side_effect = [[], ["v61", "v62"]]
        self.assertEqual(
            ("v61", False, None),
            self.fqdn_resolve(self.logger, "foo.bar.local", dnssrv="10.0.0.1"),
        )

    @patch("dns.resolver.Resolver")
    def test_148_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning list and catch_all"""
        mock_resolve.return_value.resolve.side_effect = [["v41", "v42"], ["v61", "v62"]]
        self.assertEqual(
            (["v41", "v42", "v61", "v62"], False, None),
            self.fqdn_resolve(
                self.logger, "foo.bar.local", dnssrv="10.0.0.1", catch_all=True
            ),
        )

    @patch("dns.resolver.Resolver")
    def test_149_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning covering list but no v4 and catch_all"""
        mock_resolve.return_value.resolve.side_effect = [[], ["v61", "v62"]]
        self.assertEqual(
            (["v61", "v62"], False, None),
            self.fqdn_resolve(
                self.logger, "foo.bar.local", dnssrv="10.0.0.1", catch_all=True
            ),
        )

    @patch("dns.resolver.Resolver")
    def test_150_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning list v6 only and catch_all"""
        mock_resolve.return_value.resolve.side_effect = [["v41", "v42"], []]
        self.assertEqual(
            (["v41", "v42"], False, None),
            self.fqdn_resolve(
                self.logger, "foo.bar.local", dnssrv="10.0.0.1", catch_all=True
            ),
        )

    @patch("dns.resolver.Resolver")
    def test_151_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning covering list but no v4 and catch_all"""
        mock_resolve.return_value.resolve.side_effect = [
            Exception("foo"),
            ["v61", "v62"],
        ]
        self.assertEqual(
            (["v61", "v62"], False, None),
            self.fqdn_resolve(
                self.logger, "foo.bar.local", dnssrv="10.0.0.1", catch_all=True
            ),
        )

    @patch("dns.resolver.Resolver")
    def test_152_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning list v6 only and catch_all"""
        mock_resolve.return_value.resolve.side_effect = [
            ["v41", "v42"],
            Exception("foo"),
        ]
        self.assertEqual(
            (["v41", "v42"], False, None),
            self.fqdn_resolve(
                self.logger, "foo.bar.local", dnssrv="10.0.0.1", catch_all=True
            ),
        )

    @patch("dns.resolver.Resolver")
    def test_153_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning covering list but no v4 and catch_all"""
        mock_resolve.return_value.resolve.side_effect = Mock(
            side_effect=[dns.resolver.NXDOMAIN, ["v61", "v62"]]
        )
        self.assertEqual(
            (["v61", "v62"], False, None),
            self.fqdn_resolve(
                self.logger, "foo.bar.local", dnssrv=["10.0.0.1"], catch_all=True
            ),
        )

    @patch("dns.resolver.Resolver")
    def test_154_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning list v6 only and catch_all"""
        mock_resolve.return_value.resolve.side_effect = Mock(
            side_effect=[["v41", "v42"], dns.resolver.NXDOMAIN]
        )
        self.assertEqual(
            (["v41", "v42"], False, None),
            self.fqdn_resolve(
                self.logger, "foo.bar.local", dnssrv=["10.0.0.1"], catch_all=True
            ),
        )

    @patch("dns.resolver.Resolver")
    def test_155_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning covering list but no v4 and catch_all"""
        mock_resolve.return_value.resolve.side_effect = Mock(
            side_effect=dns.resolver.NXDOMAIN
        )
        err_msg = "A: NXDOMAIN: foo.bar.local does not exist; AAAA: NXDOMAIN: foo.bar.local does not exist"
        self.assertEqual(
            ([], True, err_msg),
            self.fqdn_resolve(
                self.logger, "foo.bar.local", dnssrv=["10.0.0.1"], catch_all=True
            ),
        )

    @patch("dns.resolver.Resolver")
    def test_156_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning one value"""
        mock_resolve.return_value.resolve.return_value = ["foo"]
        self.assertEqual(
            ("foo", False, None), self.fqdn_resolve(self.logger, "foo.bar.local")
        )

    @patch("dns.resolver.Resolver")
    def test_157_helper_fqdn_resolve(self, mock_resolve):
        """successful dns-query returning two values"""
        mock_resolve.return_value.resolve.return_value = ["bar", "foo"]
        self.assertEqual(
            ("bar", False, None), self.fqdn_resolve(self.logger, "foo.bar.local")
        )

    @patch("dns.resolver.Resolver")
    def test_158_helper_fqdn_resolve(self, mock_resolve):
        """catch NXDOMAIN"""
        mock_resolve.return_value.resolve.side_effect = Mock(
            side_effect=dns.resolver.NXDOMAIN
        )
        self.assertEqual(
            (
                None,
                True,
                "A: NXDOMAIN: foo.bar.local does not exist; AAAA: NXDOMAIN: foo.bar.local does not exist",
            ),
            self.fqdn_resolve(self.logger, "foo.bar.local"),
        )

    @patch("dns.resolver.Resolver")
    def test_159_helper_fqdn_resolve(self, mock_resolve):
        """catch NoAnswer"""
        mock_resolve.return_value.resolve.side_effect = Mock(
            side_effect=dns.resolver.NoAnswer
        )
        err_msg = "A: No A record found for foo.bar.local; AAAA: No AAAA record found for foo.bar.local"
        self.assertEqual(
            (None, True, err_msg), self.fqdn_resolve(self.logger, "foo.bar.local")
        )

    @patch("dns.resolver.Resolver")
    def test_160_helper_fqdn_resolve(self, mock_resolve):
        """catch other dns related execption"""
        mock_resolve.return_value.resolve.side_effect = Mock(
            side_effect=dns.resolver.NoNameservers
        )
        err_msg = "A: DNS resolution error: All nameservers failed to answer the query.; AAAA: DNS resolution error: All nameservers failed to answer the query."
        self.assertEqual(
            (None, True, err_msg), self.fqdn_resolve(self.logger, "foo.bar.local")
        )

    @patch("dns.resolver.Resolver")
    def test_161_helper_fqdn_resolve(self, mock_resolve):
        """catch other execption"""
        mock_resolve.return_value.resolve.side_effect = Mock(
            side_effect=Exception("foo")
        )
        self.assertEqual(
            (
                None,
                True,
                "A: DNS resolution error: foo; AAAA: DNS resolution error: foo",
            ),
            self.fqdn_resolve(self.logger, "foo.bar.local"),
        )

    @patch("dns.resolver.Resolver")
    def test_162_helper_fqdn_resolve(self, mock_resolve):
        """catch NXDOMAIN on v4 and fine in v6"""
        mock_resolve.return_value.resolve.side_effect = Mock(
            side_effect=dns.resolver.NXDOMAIN
        ), ["foo"]
        self.assertEqual(
            ("foo", False, None), self.fqdn_resolve(self.logger, "foo.bar.local")
        )

    @patch("dns.resolver.Resolver")
    def test_163_helper_fqdn_resolve(self, mock_resolve):
        """catch NoAnswer on v4 and fine in v6"""
        mock_resolve.return_value.resolve.side_effect = Mock(
            side_effect=dns.resolver.NoAnswer
        ), ["foo"]
        self.assertEqual(
            ("foo", False, None), self.fqdn_resolve(self.logger, "foo.bar.local")
        )

    @patch("dns.resolver.Resolver")
    def test_164_helper_fqdn_resolve(self, mock_resolve):
        """catch other dns related execption on v4 and fine in v6"""
        mock_resolve.return_value.resolve.side_effect = ([Exception("foo"), ["foo"]],)
        self.assertEqual(
            ("foo", False, None), self.fqdn_resolve(self.logger, "foo.bar.local")
        )

    @patch("dns.resolver.Resolver")
    def test_165_helper_fqdn_resolve(self, mock_resolve):
        """catch other execption when resolving v4 but fine in v6"""
        mock_resolve.return_value.resolve.side_effect = ([Exception("foo"), ["foo"]],)
        self.assertEqual(
            ("foo", False, None), self.fqdn_resolve(self.logger, "foo.bar.local")
        )

    def test_166_helper_signature_check(self):
        """sucessful validation symmetric key"""
        mkey = '{"k": "ZndUSkZvVldvMEFiRzQ5VWNCdERtNkNBNnBTcTl4czNKVEVxdUZiaEdpZXZNUVJBVmRuSFREcDJYX2s3X0NxTA", "kty": "oct"}'
        message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}'
        self.assertEqual(
            (True, None), self.signature_check(self.logger, message, mkey, json_=True)
        )

    def test_167_helper_signature_check(self):
        """sucessful validation wrong symmetric key"""
        mkey = '{"k": "ZndUSkZvVldvMEFiRzQ5VWNCdERtNkNBNnBTcTl4czNKVEVxdUZiaEdpZXZNUVJBVmRuSFREcDJYX2s3X0NxvA", "kty": "oct"}'
        message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}'

        if int("%i%i" % (sys.version_info[0], sys.version_info[1])) <= 36:
            error = "Verification failed for all signatures[\"Failed: [InvalidJWSSignature('Verification failed',)]\"]"
        else:
            error = "Verification failed for all signatures[\"Failed: [InvalidJWSSignature('Verification failed')]\"]"
        self.assertEqual(
            (False, error), self.signature_check(self.logger, message, mkey, json_=True)
        )

    def test_168_helper_signature_check(self):
        """sucessful validation wrong symmetric key without json_ flag set"""
        mkey = '{"k": "ZndUSkZvVldvMEFiRzQ5VWNCdERtNkNBNnBTcTl4czNKVEVxdUZiaEdpZXZNUVJBVmRuSFREcDJYX2s3X0NxvA", "kty": "oct"}'
        message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}'
        if int("%i%i" % (sys.version_info[0], sys.version_info[1])) < 39:
            error = "type object argument after ** must be a mapping, not str"
        else:
            error = "jwcrypto.jwk.JWK() argument after ** must be a mapping, not str"

        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (False, error), self.signature_check(self.logger, message, mkey)
            )
        self.assertIn("ERROR:test_a2c:No jwkey extracted", lcm.output)

    def test_169_helper_signature_check(self):
        """sucessful validation invalid key"""
        mkey = "invalid key"
        message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}'
        self.assertEqual(
            (False, ""), self.signature_check(self.logger, message, mkey, json_=True)
        )

    def test_170_fqdn_in_san_check(self):
        """successful check one entry one match"""
        fqdn = "foo.bar.local"
        san_list = ["DNS:foo.bar.local"]
        self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn))

    def test_171_fqdn_in_san_check(self):
        """successful check two entries one match"""
        fqdn = "foo.bar.local"
        san_list = ["DNS:foo1.bar.local", "DNS:foo.bar.local"]
        self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn))

    def test_172_fqdn_in_san_check(self):
        """successful check two entries no DNS one match"""
        fqdn = "foo.bar.local"
        san_list = ["IP: 10.0.0.l", "DNS:foo.bar.local"]
        self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn))

    def test_173_fqdn_in_san_check(self):
        """successful check no fqdn"""
        fqdn = None
        san_list = ["IP: 10.0.0.l", "DNS:foo.bar.local"]
        self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn))

    def test_174_fqdn_in_san_check(self):
        """successful check no fqdn"""
        fqdn = ""
        san_list = ["IP: 10.0.0.l", "DNS:foo.bar.local"]
        self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn))

    def test_175_fqdn_in_san_check(self):
        """successful check blank fqdn"""
        fqdn = " "
        san_list = ["IP: 10.0.0.l", "DNS:foo.bar.local"]
        self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn))

    def test_176_fqdn_in_san_check(self):
        """successful check empty san_list"""
        fqdn = "foo.bar.local"
        san_list = []
        self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn))

    def test_177_fqdn_in_san_check(self):
        """successful check two entries one match"""
        fqdn = "foo.bar.local"
        san_list = ["foo1.bar.local", "DNS:foo.bar.local"]
        self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn))

    def test_178_fqdn_in_san_check(self):
        """successful check two entries one match"""
        fqdn = "foo.bar.local"
        san_list = ["foo1.bar.local"]
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn))
        self.assertIn(
            "ERROR:test_a2c:Error during SAN check. SAN split failed: foo1.bar.local",
            lcm.output,
        )

    def test_179_sha256_hash_hex(self):
        """sha256 digest as hex file"""
        self.assertEqual(
            "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
            self.sha256_hash_hex(self.logger, "foo"),
        )

    def test_180_sha256_hash_hex(self):
        """sha256 digest as hex file"""
        self.assertEqual(
            "fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9",
            self.sha256_hash_hex(self.logger, "bar"),
        )

    def test_181_sha256_hash(self):
        """sha256 digest"""
        self.assertEqual(
            b"LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
            self.b64_url_encode(self.logger, self.sha256_hash(self.logger, "foo")),
        )

    def test_182_sha256_hash(self):
        """sha256 digest"""
        self.assertEqual(
            b"_N4rLtula_QIYB-3If6bXDONEO5CnqBPrlURto-_j7k",
            self.b64_url_encode(self.logger, self.sha256_hash(self.logger, "bar")),
        )

    def test_183_b64_encode(self):
        """base64 encode string"""
        self.assertEqual("Zm9v", self.b64_encode(self.logger, b"foo"))

    def test_184_b64_encode(self):
        """base64 encode string"""
        self.assertEqual("YmFyMQ==", self.b64_encode(self.logger, b"bar1"))

    def test_185_b64_encode(self):
        """base64 encode string"""
        self.assertEqual("YmFyMTI=", self.b64_encode(self.logger, b"bar12"))

    def test_186_cert_der2pem(self):
        """test cert_der2pem"""
        b64 = "MIIETjCCAjagAwIBAgIRAIG11e4S8ErJuwCYAKsoU3UwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAxMGc3ViLWNhMB4XDTIxMDYxMjA2MjMzOFoXDTIzMDYwMjA2MjMzOFowGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1rqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDaRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqYZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGjgZgwgZUwCwYDVR0PBAQDAgXgMBkGA1UdEQQSMBCCDmZvbzEuYmFyLmxvY2FsMB0GA1UdDgQWBBReDKlEWwro02ljWMCi10HMqhDmbzAfBgNVHSMEGDAWgBSDJ855iatD1k7LCUzmM5yhe4IzeDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEAhv7Jco6VjT25FuyOz/C0N5+q2M8sqjcDDYMwUTKXVkIc7/lSsubL8z64eS4I5iBecNOlPXASMoMe0KbdrvzqItYgeisC08rnWQayuDr/dj2Y/v4WptZdTPc0pWZQ7LUSxcZaydMFsIKxtfO2HR84DqrUbpvDfVSP7/UiN2O0TbSBiEC6Xayu6IudGZ9naHTAXzTau6SejcbH+0jWZsDXd1SbDPd3a+ZcHbDLIZAzsjcurleDPS54PIXjblOgMrsheDq/wzxKtvLOZEe8Gr6THwtX6uS0oQ72BFNGfZVVPFiL/q0Dvj2FveBtv7k14QcBqHutE4pEpYb/kcU7cxCVgGlUw8Q8trYQhBB37X9dOHjC2G8cyCeyVr+xfUE12wTKZDRIXjG3FMpKgeB4oNYPWA5m/1GBOGddhmogIB8GXeenDcAjBdVOFuuOrMInHLnLD9w7iEiopfx+six3Nxpo3thDV4xdiTZsWp9ojZhQzW8haEQleJ3Xyl65UuZKHyrRJ0OWR4LRkNwJitG5F0MYg8bjgik/cHTwzIB0HXgnaVeMBJY3sOkvCpAlTGZe1GL9foWIeFkprPG4cePrjtC3Mn8rHH0pIi1mdkcAIdexYdg/qlroKk2ROLXnX5LHmrM1CDZQphgyzLETdwXQdTBOJvc8FsDPhp5p+iqgT2e16QI="
        result = b"-----BEGIN CERTIFICATE-----\nMIIETjCCAjagAwIBAgIRAIG11e4S8ErJuwCYAKsoU3UwDQYJKoZIhvcNAQELBQAw\nETEPMA0GA1UEAxMGc3ViLWNhMB4XDTIxMDYxMjA2MjMzOFoXDTIzMDYwMjA2MjMz\nOFowGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUA\nA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1\nrqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDa\nRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqY\nZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW\n/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA\n2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGjgZgwgZUwCwYDVR0P\nBAQDAgXgMBkGA1UdEQQSMBCCDmZvbzEuYmFyLmxvY2FsMB0GA1UdDgQWBBReDKlE\nWwro02ljWMCi10HMqhDmbzAfBgNVHSMEGDAWgBSDJ855iatD1k7LCUzmM5yhe4Iz\neDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAN\nBgkqhkiG9w0BAQsFAAOCAgEAhv7Jco6VjT25FuyOz/C0N5+q2M8sqjcDDYMwUTKX\nVkIc7/lSsubL8z64eS4I5iBecNOlPXASMoMe0KbdrvzqItYgeisC08rnWQayuDr/\ndj2Y/v4WptZdTPc0pWZQ7LUSxcZaydMFsIKxtfO2HR84DqrUbpvDfVSP7/UiN2O0\nTbSBiEC6Xayu6IudGZ9naHTAXzTau6SejcbH+0jWZsDXd1SbDPd3a+ZcHbDLIZAz\nsjcurleDPS54PIXjblOgMrsheDq/wzxKtvLOZEe8Gr6THwtX6uS0oQ72BFNGfZVV\nPFiL/q0Dvj2FveBtv7k14QcBqHutE4pEpYb/kcU7cxCVgGlUw8Q8trYQhBB37X9d\nOHjC2G8cyCeyVr+xfUE12wTKZDRIXjG3FMpKgeB4oNYPWA5m/1GBOGddhmogIB8G\nXeenDcAjBdVOFuuOrMInHLnLD9w7iEiopfx+six3Nxpo3thDV4xdiTZsWp9ojZhQ\nzW8haEQleJ3Xyl65UuZKHyrRJ0OWR4LRkNwJitG5F0MYg8bjgik/cHTwzIB0HXgn\naVeMBJY3sOkvCpAlTGZe1GL9foWIeFkprPG4cePrjtC3Mn8rHH0pIi1mdkcAIdex\nYdg/qlroKk2ROLXnX5LHmrM1CDZQphgyzLETdwXQdTBOJvc8FsDPhp5p+iqgT2e1\n6QI=\n-----END CERTIFICATE-----\n"
        der = self.b64_decode(self.logger, b64)
        self.assertEqual(result, self.cert_der2pem(der))

    def test_187_cert_pem2der(self):
        """test cert_der2pem"""
        cert = """-----BEGIN CERTIFICATE-----
MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE
CxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMTA0MDkxNTUy
MDBaFw0yNjA0MDkxNTUyMDBaMBgxFjAUBgNVBAMTDWVzdGNsaWVudC5lc3QwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAn6IqwTE1RvZUm3gelpu4tmrd
Fj8Ub98J1YeQz7qrew5iA81NeH9tR484edjcY0ieOt3e1MfxJoziWtaeqxpsfytm
VB/i+850kVZmvRCR1jhW/4AzidkVBMQiCR5erPmmheeCxbKkto0rHb7ziRA+F8/f
ZLKfLNsahEQPxDuMItyQFCOQFHh8Hfuend2NgsQKeZ1r5Czf3n5Q6NFff7HG+MDe
NDNdPB3ShgcvvNCFUS1z615/GIItfSqcWTAVaJ7436cA7yy5y4+0SvjfXYtHYfyt
hBj/5UqlUmjni8Irj5K8uEtb1YUujmvlTTbzPkhYqIkSoyr7t21Dz+gcYn49AgMB
AAGjgZ8wgZwwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUN3Z0iLv1FE17DCDBfpxW
2P+5+kIwCwYDVR0PBAQDAgO4MBMGA1UdJQQMMAoGCCsGAQUFBwMCMBgGA1UdEQQR
MA+CDWVzdGNsaWVudC5lc3QwEQYJYIZIAYb4QgEBBAQDAgWgMB4GCWCGSAGG+EIB
DQQRFg94Y2EgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggIBACMAHHH4/0eA
XbS/uKsIjLN1QPnnzgjxC0xoUon8UVM0PUMH+FMg6rs21Xyl5tn5iItmvKI9c3ak
AZ00RUQKVdmJVFRUKywmfF7n5epBpXtWJrSH817NT9GOp+PO5VUTDV5VkvpVLoy7
WzThrheLKz1nC1dWowRz86tcBLAsC1zT17fsNZXQDuv4LiQQXs7QKhUU75r1Ixrd
BPeBQSP5skGpWxm8sapQSfOALoXu1pSoGIr6tqvNGuEoZGvUuWeQHG/G8c2ufL+6
lEzZBBCd6e2tErkqD/vqfCRzbLcGgSPX0HVWdkjH09nHWXI5UhNr2YgGF7YvSTKW
JfbDVlTql1BuSn2yTQtDk4E8k9BLr8WfqFSZvYrivT9Ax1n3BD9jvQL5+QRdioH1
kqNGMme0Pb43pHciX4hu9L5rGenZRmxeGXZ78uSOR+n2bGxAMw1OY7Rx/lsNSKWD
SN+7xIrwjjXO5Uthev1ecrLAK2+EpjITa6Y85ms39V4ypCEdujkKEBeVxuN8DdMJ
2GaFGluSRZeYZ0LAPfYr5sp6G6904WF+PcT0WjGenH4PJLXrAttbhhvQxXU0Q8s2
CUwUHy5OT/DW3POq7WETc+zmFGwZqiP3W9gmN0hHXsKqkNmz2RYgoH57lPS1PJb0
klGUNHG98CtsmlhrivhSTJWqSIOfyKGF
-----END CERTIFICATE-----"""
        result = "MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMTA0MDkxNTUyMDBaFw0yNjA0MDkxNTUyMDBaMBgxFjAUBgNVBAMTDWVzdGNsaWVudC5lc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAn6IqwTE1RvZUm3gelpu4tmrdFj8Ub98J1YeQz7qrew5iA81NeH9tR484edjcY0ieOt3e1MfxJoziWtaeqxpsfytmVB/i+850kVZmvRCR1jhW/4AzidkVBMQiCR5erPmmheeCxbKkto0rHb7ziRA+F8/fZLKfLNsahEQPxDuMItyQFCOQFHh8Hfuend2NgsQKeZ1r5Czf3n5Q6NFff7HG+MDeNDNdPB3ShgcvvNCFUS1z615/GIItfSqcWTAVaJ7436cA7yy5y4+0SvjfXYtHYfythBj/5UqlUmjni8Irj5K8uEtb1YUujmvlTTbzPkhYqIkSoyr7t21Dz+gcYn49AgMBAAGjgZ8wgZwwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUN3Z0iLv1FE17DCDBfpxW2P+5+kIwCwYDVR0PBAQDAgO4MBMGA1UdJQQMMAoGCCsGAQUFBwMCMBgGA1UdEQQRMA+CDWVzdGNsaWVudC5lc3QwEQYJYIZIAYb4QgEBBAQDAgWgMB4GCWCGSAGG+EIBDQQRFg94Y2EgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggIBACMAHHH4/0eAXbS/uKsIjLN1QPnnzgjxC0xoUon8UVM0PUMH+FMg6rs21Xyl5tn5iItmvKI9c3akAZ00RUQKVdmJVFRUKywmfF7n5epBpXtWJrSH817NT9GOp+PO5VUTDV5VkvpVLoy7WzThrheLKz1nC1dWowRz86tcBLAsC1zT17fsNZXQDuv4LiQQXs7QKhUU75r1IxrdBPeBQSP5skGpWxm8sapQSfOALoXu1pSoGIr6tqvNGuEoZGvUuWeQHG/G8c2ufL+6lEzZBBCd6e2tErkqD/vqfCRzbLcGgSPX0HVWdkjH09nHWXI5UhNr2YgGF7YvSTKWJfbDVlTql1BuSn2yTQtDk4E8k9BLr8WfqFSZvYrivT9Ax1n3BD9jvQL5+QRdioH1kqNGMme0Pb43pHciX4hu9L5rGenZRmxeGXZ78uSOR+n2bGxAMw1OY7Rx/lsNSKWDSN+7xIrwjjXO5Uthev1ecrLAK2+EpjITa6Y85ms39V4ypCEdujkKEBeVxuN8DdMJ2GaFGluSRZeYZ0LAPfYr5sp6G6904WF+PcT0WjGenH4PJLXrAttbhhvQxXU0Q8s2CUwUHy5OT/DW3POq7WETc+zmFGwZqiP3W9gmN0hHXsKqkNmz2RYgoH57lPS1PJb0klGUNHG98CtsmlhrivhSTJWqSIOfyKGF"
        self.assertEqual(result, self.b64_encode(self.logger, self.cert_pem2der(cert)))

    def test_188_helper_cert_extensions_get(self):
        """test cert_san_get for a single SAN and recode = False"""
        cert = """-----BEGIN CERTIFICATE-----
MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE
CxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMTA0MDkxNTUy
MDBaFw0yNjA0MDkxNTUyMDBaMBgxFjAUBgNVBAMTDWVzdGNsaWVudC5lc3QwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAn6IqwTE1RvZUm3gelpu4tmrd
Fj8Ub98J1YeQz7qrew5iA81NeH9tR484edjcY0ieOt3e1MfxJoziWtaeqxpsfytm
VB/i+850kVZmvRCR1jhW/4AzidkVBMQiCR5erPmmheeCxbKkto0rHb7ziRA+F8/f
ZLKfLNsahEQPxDuMItyQFCOQFHh8Hfuend2NgsQKeZ1r5Czf3n5Q6NFff7HG+MDe
NDNdPB3ShgcvvNCFUS1z615/GIItfSqcWTAVaJ7436cA7yy5y4+0SvjfXYtHYfyt
hBj/5UqlUmjni8Irj5K8uEtb1YUujmvlTTbzPkhYqIkSoyr7t21Dz+gcYn49AgMB
AAGjgZ8wgZwwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUN3Z0iLv1FE17DCDBfpxW
2P+5+kIwCwYDVR0PBAQDAgO4MBMGA1UdJQQMMAoGCCsGAQUFBwMCMBgGA1UdEQQR
MA+CDWVzdGNsaWVudC5lc3QwEQYJYIZIAYb4QgEBBAQDAgWgMB4GCWCGSAGG+EIB
DQQRFg94Y2EgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggIBACMAHHH4/0eA
XbS/uKsIjLN1QPnnzgjxC0xoUon8UVM0PUMH+FMg6rs21Xyl5tn5iItmvKI9c3ak
AZ00RUQKVdmJVFRUKywmfF7n5epBpXtWJrSH817NT9GOp+PO5VUTDV5VkvpVLoy7
WzThrheLKz1nC1dWowRz86tcBLAsC1zT17fsNZXQDuv4LiQQXs7QKhUU75r1Ixrd
BPeBQSP5skGpWxm8sapQSfOALoXu1pSoGIr6tqvNGuEoZGvUuWeQHG/G8c2ufL+6
lEzZBBCd6e2tErkqD/vqfCRzbLcGgSPX0HVWdkjH09nHWXI5UhNr2YgGF7YvSTKW
JfbDVlTql1BuSn2yTQtDk4E8k9BLr8WfqFSZvYrivT9Ax1n3BD9jvQL5+QRdioH1
kqNGMme0Pb43pHciX4hu9L5rGenZRmxeGXZ78uSOR+n2bGxAMw1OY7Rx/lsNSKWD
SN+7xIrwjjXO5Uthev1ecrLAK2+EpjITa6Y85ms39V4ypCEdujkKEBeVxuN8DdMJ
2GaFGluSRZeYZ0LAPfYr5sp6G6904WF+PcT0WjGenH4PJLXrAttbhhvQxXU0Q8s2
CUwUHy5OT/DW3POq7WETc+zmFGwZqiP3W9gmN0hHXsKqkNmz2RYgoH57lPS1PJb0
klGUNHG98CtsmlhrivhSTJWqSIOfyKGF
-----END CERTIFICATE-----"""
        self.assertEqual(
            [
                "MAA=",
                "BBQ3dnSIu/UUTXsMIMF+nFbY/7n6Qg==",
                "AwIDuA==",
                "MAoGCCsGAQUFBwMC",
                "MA+CDWVzdGNsaWVudC5lc3Q=",
                "AwIFoA==",
                "Fg94Y2EgY2VydGlmaWNhdGU=",
            ],
            self.cert_extensions_get(self.logger, cert, recode=False),
        )

    def test_189_helper_cert_extensions_get(self):
        """test cert_san_get for a single SAN and recode = True"""
        cert = "MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMTA0MDkxNTUyMDBaFw0yNjA0MDkxNTUyMDBaMBgxFjAUBgNVBAMTDWVzdGNsaWVudC5lc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAn6IqwTE1RvZUm3gelpu4tmrdFj8Ub98J1YeQz7qrew5iA81NeH9tR484edjcY0ieOt3e1MfxJoziWtaeqxpsfytmVB/i+850kVZmvRCR1jhW/4AzidkVBMQiCR5erPmmheeCxbKkto0rHb7ziRA+F8/fZLKfLNsahEQPxDuMItyQFCOQFHh8Hfuend2NgsQKeZ1r5Czf3n5Q6NFff7HG+MDeNDNdPB3ShgcvvNCFUS1z615/GIItfSqcWTAVaJ7436cA7yy5y4+0SvjfXYtHYfythBj/5UqlUmjni8Irj5K8uEtb1YUujmvlTTbzPkhYqIkSoyr7t21Dz+gcYn49AgMBAAGjgZ8wgZwwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUN3Z0iLv1FE17DCDBfpxW2P+5+kIwCwYDVR0PBAQDAgO4MBMGA1UdJQQMMAoGCCsGAQUFBwMCMBgGA1UdEQQRMA+CDWVzdGNsaWVudC5lc3QwEQYJYIZIAYb4QgEBBAQDAgWgMB4GCWCGSAGG+EIBDQQRFg94Y2EgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggIBACMAHHH4/0eAXbS/uKsIjLN1QPnnzgjxC0xoUon8UVM0PUMH+FMg6rs21Xyl5tn5iItmvKI9c3akAZ00RUQKVdmJVFRUKywmfF7n5epBpXtWJrSH817NT9GOp+PO5VUTDV5VkvpVLoy7WzThrheLKz1nC1dWowRz86tcBLAsC1zT17fsNZXQDuv4LiQQXs7QKhUU75r1IxrdBPeBQSP5skGpWxm8sapQSfOALoXu1pSoGIr6tqvNGuEoZGvUuWeQHG/G8c2ufL+6lEzZBBCd6e2tErkqD/vqfCRzbLcGgSPX0HVWdkjH09nHWXI5UhNr2YgGF7YvSTKWJfbDVlTql1BuSn2yTQtDk4E8k9BLr8WfqFSZvYrivT9Ax1n3BD9jvQL5+QRdioH1kqNGMme0Pb43pHciX4hu9L5rGenZRmxeGXZ78uSOR+n2bGxAMw1OY7Rx/lsNSKWDSN+7xIrwjjXO5Uthev1ecrLAK2+EpjITa6Y85ms39V4ypCEdujkKEBeVxuN8DdMJ2GaFGluSRZeYZ0LAPfYr5sp6G6904WF+PcT0WjGenH4PJLXrAttbhhvQxXU0Q8s2CUwUHy5OT/DW3POq7WETc+zmFGwZqiP3W9gmN0hHXsKqkNmz2RYgoH57lPS1PJb0klGUNHG98CtsmlhrivhSTJWqSIOfyKGF"
        self.assertEqual(
            [
                "MAA=",
                "BBQ3dnSIu/UUTXsMIMF+nFbY/7n6Qg==",
                "AwIDuA==",
                "MAoGCCsGAQUFBwMC",
                "MA+CDWVzdGNsaWVudC5lc3Q=",
                "AwIFoA==",
                "Fg94Y2EgY2VydGlmaWNhdGU=",
            ],
            self.cert_extensions_get(self.logger, cert, recode=True),
        )

    def test_190_csr_dn_get(self):
        """ " test csr_dn_get"""
        csr = "MIICjDCCAXQCAQAwFzEVMBMGA1UEAwwMdGVzdF9yZXF1ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy6VRYaXuLS/DPa+pf5IEwycpjPfZ2vTFlvjvhwu9A3yaQQn4kD33Fu4p+zorIVmsjgpkUel2104lxFeSV081YKGzOtsajzaIRZhF7mHG5aVA8cahVPHlnxT06kO8F545ZsxE6T22tCbrLJpZk4hcaQUmGcZDWZqI7CXhbi1LSuIVIAAF0lTGMsanIM97ZEtA9mhtxFd7TsLlJpmls1l8MTavFcBtAZXqAsi4LnzEbozSjaLnuXsTe7tPmOS0uOLX+EcTAH/SxkbIg3whehTzC/sVmz5STbpklq3QuudtUl/509fpSa/UQ+WFOUUC3GhiiMM813ZsbAnt1BJepKtrfQIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHREEFjAUghJ0ZXN0X3JlcXVlc3QubG9jYWwwDQYJKoZIhvcNAQELBQADggEBAFcKxjJXHBVjzqF3e6fCkDbF1JnVtNyDxZB+h4b5lI7SIuA9O/+0hcl/njeFB1gJbRODws10kKkiAYLXvS/fsLJg1gdyFPmDiCd2nJhDUCBcGmVYraGhV45x67jcUmoeqSSj5KyUY9zI+v3nANvZMf+g31ORtW8PuspkiiLJiyuGzFS67DGovbcBRrM67IApO7p04VwLA0hssFUa+wF9PUWIyu9TLx+w0rNYcp3d1wkJ905TB8gwOKXeB0RwkporlOF3KEcT+ueKZE04867bjZ/ZpiuIDFnO23MsUKLKU9ebWgwYN/xzxA8sroM69y+Acpt9Zwn3vRjVlT92Ztl218Q="
        self.assertEqual("CN=test_request", self.csr_dn_get(self.logger, csr))

    def test_191_logger_setup(self):
        """logger setup"""
        self.assertTrue(self.logger_setup(False))

    def test_192_logger_setup(self):
        """logger setup"""
        self.assertTrue(self.logger_setup(True))

    @patch("acme2certifier.acme_srv.helpers.logging_utils.load_config")
    def test_193_logger_setup(self, mock_load_cfg):
        """logger setup"""
        mock_load_cfg.return_value = {
            "Helper": {
                "log_format": "%(asctime)s - acme2certifier - %(levelname)s - %(message)s"
            }
        }
        self.assertTrue(self.logger_setup(True))

    @patch("configparser.RawConfigParser")
    def test_194_load_config(self, mock_parser):
        """load config"""
        self.assertTrue(self.load_config(None, None, None))

    @patch("configparser.RawConfigParser")
    def test_195_load_config(self, mock_parser):
        """load config"""
        self.assertTrue(self.load_config(self.logger, None, None))

    @patch.dict("os.environ", {"ACME_SRV_CONFIGFILE": "ACME_SRV_CONFIGFILE"})
    @patch("configparser.RawConfigParser")
    def test_196_load_config(self, mock_parser):
        """load config"""
        self.assertTrue(self.load_config(None, None, None))

    def test_197_logger_info(self):
        """logger info"""
        addr = "addr"
        url = "url"
        data_dic = {"foo": "bar"}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.logger_info(self.logger, addr, url, data_dic)
        self.assertIn("INFO:test_a2c:addr url {'foo': 'bar'}", lcm.output)

    def test_198_logger_info(self):
        """logger info replace remove Nonce in header"""
        addr = "addr"
        url = "url"
        data_dic = {"foo": "bar", "header": {"Replay-Nonce": "Replay-Nonce"}}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.logger_info(self.logger, addr, url, data_dic)
        self.assertIn(
            "INFO:test_a2c:addr url {'foo': 'bar', 'header': {'Replay-Nonce': '- modified -'}}",
            lcm.output,
        )

    def test_199_logger_info(self):
        """logger info replace remnove cert"""
        addr = "addr"
        url = "/acme/cert/secret"
        data_dic = {"foo": "bar", "data": {"Replay-Nonce": "Replay-Nonce"}}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.logger_info(self.logger, addr, url, data_dic)
        self.assertIn(
            "INFO:test_a2c:addr /acme/cert/secret {'foo': 'bar', 'data': ' - certificate - '}",
            lcm.output,
        )

    def test_200_logger_info(self):
        """logger info replace remove token"""
        addr = "addr"
        url = "url"
        data_dic = {"foo": "bar", "data": {"token": "token"}}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.logger_info(self.logger, addr, url, data_dic)
        self.assertIn(
            "INFO:test_a2c:addr url {'foo': 'bar', 'data': {'token': '- modified -'}}",
            lcm.output,
        )

    def test_201_logger_info(self):
        """logger info replace remove single token in challenges"""
        addr = "addr"
        url = "url"
        data_dic = {
            "foo": "bar",
            "data": {"challenges": [{"foo1": "bar1", "token": "token1"}]},
        }
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.logger_info(self.logger, addr, url, data_dic)
        self.assertIn(
            "INFO:test_a2c:addr url {'foo': 'bar', 'data': {'challenges': [{'foo1': 'bar1', 'token': '- modified - '}]}}",
            lcm.output,
        )

    def test_202_logger_info(self):
        """logger info replace remove two token in challenges"""
        addr = "addr"
        url = "url"
        data_dic = {
            "foo": "bar",
            "data": {
                "challenges": [
                    {"foo1": "bar1", "token": "token1"},
                    {"foo2": "bar2", "token": "token1"},
                ]
            },
        }
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.logger_info(self.logger, addr, url, data_dic)
        self.assertIn(
            "INFO:test_a2c:addr url {'foo': 'bar', 'data': {'challenges': [{'foo1': 'bar1', 'token': '- modified - '}, {'foo2': 'bar2', 'token': '- modified - '}]}}",
            lcm.output,
        )

    @patch("builtins.print")
    def test_203_print_debug(self, mock_print):
        """test print_debug"""
        self.print_debug(False, "test")
        self.assertFalse(mock_print.called)

    @patch("builtins.print")
    def test_204_print_debug(self, mock_print):
        """test print_debug"""
        self.print_debug(True, "test")
        self.assertTrue(mock_print.called)

    def test_205_jwk_thumbprint_get(self):
        """test jwk_thumbprint_get with empty pubkey"""
        pub_key = None
        self.assertFalse(self.jwk_thumbprint_get(self.logger, pub_key))

    @patch("jwcrypto.jwk.JWK")
    def test_206_jwk_thumbprint_get(self, mock_jwk):
        """test jwk_thumbprint_get with  pubkey"""
        pub_key = {"pub_key": "pub_key"}
        mock_jwk = Mock()
        self.assertTrue(self.jwk_thumbprint_get(self.logger, pub_key))

    @patch("jwcrypto.jwk.JWK")
    def test_207_jwk_thumbprint_get(self, mock_jwk):
        """test jwk_thumbprint_get with  pubkey"""
        pub_key = {"pub_key": "pub_key"}
        mock_jwk.side_effect = Exception("exc_jwk_jwk")
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.jwk_thumbprint_get(self.logger, pub_key))
        self.assertIn(
            "ERROR:test_a2c:Could not get the JWKEY thumbprint from public key: exc_jwk_jwk",
            lcm.output,
        )

    @patch("socket.AF_INET")
    def test_208_allowed_gai_family(self, mock_sock):
        """test allowed_gai_family"""
        self.assertTrue(self.allowed_gai_family())

    def test_209_validate_csr(self):
        """patched_create_connection"""
        self.assertTrue(self.validate_csr(self.logger, "oder_dic", "csr"))

    @patch("acme2certifier.acme_srv.helpers.network.proxystring_convert")
    @patch("ssl.DER_cert_to_PEM_cert")
    @patch("ssl.SSLContext.wrap_socket")
    @patch("socks.socksocket")
    def test_210_servercert_get(self, mock_sock, mock_context, mock_cert, mock_convert):
        """test servercert get"""
        mock_convert.return_value = ("proxy_proto", "proxy_addr", "proxy_port")
        mock_sock = Mock()
        mock_context = Mock()
        mock_cert.return_value = "foo"
        self.assertEqual("foo", self.servercert_get(self.logger, "hostname"))
        self.assertFalse(mock_convert.called)

    @patch("acme2certifier.acme_srv.helpers.network.ipv6_chk")
    @patch("acme2certifier.acme_srv.helpers.network.proxystring_convert")
    @patch("ssl.DER_cert_to_PEM_cert")
    @patch("ssl.SSLContext.wrap_socket")
    @patch("socket.socket")
    @patch("socks.socksocket")
    def test_211_servercert_get(
        self, mock_sock, mock_ssock, mock_context, mock_cert, mock_convert, mock_ipchk
    ):
        """test servercert get ippv6"""
        mock_convert.return_value = ("proxy_proto", "proxy_addr", "proxy_port")
        mock_ipchk.return_value = True
        mock_context = Mock()
        mock_cert.return_value = "foo"
        self.assertEqual("foo", self.servercert_get(self.logger, "hostname"))
        self.assertTrue(mock_ssock.called)
        self.assertFalse(mock_sock.called)

    @patch("acme2certifier.acme_srv.helpers.network.proxystring_convert")
    @patch("ssl.DER_cert_to_PEM_cert")
    @patch("ssl.SSLContext.wrap_socket")
    @patch("socket.socket")
    @patch("socks.socksocket")
    def test_212_servercert_get(
        self, mock_sock, mock_ssock, mock_context, mock_cert, mock_convert
    ):
        """test servercert get with proxy"""
        mock_convert.return_value = ("proxy_proto", "proxy_addr", "proxy_port")
        mock_context = Mock()
        mock_cert.return_value = "foo"
        self.assertEqual(
            "foo", self.servercert_get(self.logger, "hostname", 443, "proxy")
        )
        self.assertTrue(mock_convert.called)
        self.assertFalse(mock_ssock.called)

    @patch("ssl.DER_cert_to_PEM_cert")
    @patch("ssl.SSLContext.wrap_socket")
    @patch("socks.socksocket")
    def test_213_servercert_get(self, mock_sock, mock_context, mock_cert):
        """test servercert exception"""
        mock_sock = Mock()
        mock_context.side_effect = Exception("exc_warp_sock")
        mock_cert.return_value = "foo"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(None, self.servercert_get(self.logger, "hostname", 443))
        self.assertFalse(mock_cert.called)
        self.assertIn(
            "ERROR:test_a2c:Could not get peer certificate. Error: exc_warp_sock",
            lcm.output,
        )

    @patch("ssl.TLSVersion")
    @patch("acme2certifier.acme_srv.helpers.network.proxystring_convert")
    @patch("ssl.DER_cert_to_PEM_cert")
    @patch("ssl.SSLContext.wrap_socket")
    @patch("socks.socksocket")
    def test_214_servercert_get(
        self, mock_sock, mock_context, mock_cert, mock_convert, map_min_version
    ):
        """test servercert get"""
        mock_convert.return_value = ("proxy_proto", "proxy_addr", "proxy_port")
        mock_sock = Mock()
        mock_context = Mock()
        mock_cert.return_value = "foo"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual("foo", self.servercert_get(self.logger, "hostname"))
        self.assertIn(
            "ERROR:test_a2c:Error while getting the peer certifiate: minimum tls version not supported",
            lcm.output,
        )
        self.assertFalse(mock_convert.called)

    @patch("dns.resolver.Resolver")
    @patch("dns.resolver.resolve")
    def test_215_txt_get(self, mock_resolve, mock_res):
        """successful dns-query returning one txt record"""
        resp_obj = Mock()
        resp_obj.strings = ["foo", "bar"]
        mock_resolve.return_value = [resp_obj]
        self.assertEqual(["foo"], self.txt_get(self.logger, "foo", "10.0.0.1"))
        self.assertTrue(mock_res.called)

    @patch("dns.resolver.resolve")
    def test_216_txt_get(self, mock_resolve):
        """successful dns-query returning one txt record"""
        resp_obj = Mock()
        resp_obj.strings = ["foo", "bar"]
        mock_resolve.return_value = [resp_obj]
        self.assertEqual(["foo"], self.txt_get(self.logger, "foo"))

    @patch("dns.resolver.resolve")
    def test_217_txt_get(self, mock_resolve):
        """successful dns-query returning one txt record"""
        resp_obj1 = Mock()
        resp_obj1.strings = ["foo1", "bar1"]
        resp_obj2 = Mock()
        resp_obj2.strings = ["foo2", "bar2"]
        mock_resolve.return_value = [resp_obj1, resp_obj2]
        self.assertEqual(["foo1", "foo2"], self.txt_get(self.logger, "foo"))

    @patch("dns.resolver.resolve")
    def test_218_txt_get(self, mock_resolve):
        """successful dns-query returning one txt record"""
        mock_resolve.side_effect = Exception("mock_resolve")
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.txt_get(self.logger, "foo"))
        self.assertIn(
            "ERROR:test_a2c:Could not get TXT record: mock_resolve", lcm.output
        )

    def test_219_proxystring_convert(self):
        """convert proxy_string http"""
        self.assertEqual(
            (3, "proxy", 8080),
            self.proxystring_convert(self.logger, "http://proxy:8080"),
        )

    def test_220_proxystring_convert(self):
        """convert proxy_string socks4"""
        self.assertEqual(
            (1, "proxy", 8080),
            self.proxystring_convert(self.logger, "socks4://proxy:8080"),
        )

    def test_221_proxystring_convert(self):
        """convert proxy_string socks5"""
        self.assertEqual(
            (2, "proxy", 8080),
            self.proxystring_convert(self.logger, "socks5://proxy:8080"),
        )

    def test_222_proxystring_convert(self):
        """convert proxy_string unknown protocol"""
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (None, "proxy", 8080),
                self.proxystring_convert(self.logger, "unk://proxy:8080"),
            )
        self.assertIn(
            "ERROR:test_a2c:Unknown proxy protocol: unk",
            lcm.output,
        )

    def test_223_proxystring_convert(self):
        """convert proxy_string unknown protocol"""
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (3, "proxy", None),
                self.proxystring_convert(self.logger, "http://proxy:ftp"),
            )
        self.assertIn("ERROR:test_a2c:Unknown proxy port: ftp", lcm.output)

    def test_224_proxystring_convert(self):
        """convert proxy_string porxy sting without protocol"""
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (None, None, None), self.proxystring_convert(self.logger, "proxy")
            )
        self.assertIn(
            "ERROR:test_a2c:Error while splitting proxy_server string: proxy",
            lcm.output,
        )
        self.assertIn(
            "ERROR:test_a2c:proxy_proto (None), proxy_addr (None) or proxy_port (None) missing",
            lcm.output,
        )

    def test_225_proxystring_convert(self):
        """convert proxy_string porxy sting without port"""
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (None, None, None),
                self.proxystring_convert(self.logger, "http://proxy"),
            )
        self.assertIn(
            "ERROR:test_a2c:Error while splitting proxy into host/port: proxy",
            lcm.output,
        )
        self.assertIn(
            "ERROR:test_a2c:proxy_proto (http), proxy_addr (None) or proxy_port (None) missing",
            lcm.output,
        )

    def test_226_proxy_check(self):
        """check proxy for empty list"""
        fqdn = "foo.bar.local"
        proxy_list = {}
        self.assertFalse(self.proxy_check(self.logger, fqdn, proxy_list))

    def test_227_proxy_check(self):
        """check proxy - no match"""
        fqdn = "foo.bar.local"
        proxy_list = {"foo1.bar.local": "proxy_match"}
        self.assertFalse(self.proxy_check(self.logger, fqdn, proxy_list))

    def test_228_proxy_check(self):
        """check proxy - single entry"""
        fqdn = "foo.bar.local"
        proxy_list = {"foo.bar.local": "proxy_match"}
        self.assertEqual("proxy_match", self.proxy_check(self.logger, fqdn, proxy_list))

    def test_229_proxy_check(self):
        """check proxy  - multiple entry"""
        fqdn = "foo.bar.local"
        proxy_list = {"bar.bar.local": "proxy_nomatch", "foo.bar.local": "proxy_match"}
        self.assertEqual("proxy_match", self.proxy_check(self.logger, fqdn, proxy_list))

    def test_230_proxy_check(self):
        """check proxy  -  multiple entrie domain match"""
        fqdn = "foo.bar.local"
        proxy_list = {"bar.bar.local": "proxy_nomatch", "bar.local$": "proxy_match"}
        self.assertEqual("proxy_match", self.proxy_check(self.logger, fqdn, proxy_list))

    def test_231_proxy_check(self):
        """check proxy for empty list  multiple entrie domain match"""
        fqdn = "foo.bar.local"
        proxy_list = {"bar.local$": "proxy_nomatch", "foo.bar.local$": "proxy_match"}
        self.assertEqual("proxy_match", self.proxy_check(self.logger, fqdn, proxy_list))

    def test_232_proxy_check(self):
        """check proxy - multiple entrie domain match"""
        fqdn = "foo.bar.local"
        proxy_list = {"bar.local$": "proxy_match", "foo1.bar.local$": "proxy_nomatch"}
        self.assertEqual("proxy_match", self.proxy_check(self.logger, fqdn, proxy_list))

    def test_233_proxy_check(self):
        """check proxy - wildcard"""
        fqdn = "foo.bar.local"
        proxy_list = {"foo1.bar.local$": "proxy_nomatch", "*.bar.local$": "proxy_match"}
        self.assertEqual("proxy_match", self.proxy_check(self.logger, fqdn, proxy_list))

    def test_234_proxy_check(self):
        """check proxy - wildcard"""
        fqdn = "foo.bar.local"
        proxy_list = {".local$": "proxy_nomatch", "*.bar.local$": "proxy_match"}
        self.assertEqual("proxy_match", self.proxy_check(self.logger, fqdn, proxy_list))

    def test_235_proxy_check(self):
        """check proxy - wildcard"""
        fqdn = "local"
        proxy_list = {"local$": "proxy_match", "*.bar.local$": "proxy_no_match"}
        self.assertEqual("proxy_match", self.proxy_check(self.logger, fqdn, proxy_list))

    def test_236_proxy_check(self):
        """check proxy - wildcard"""
        fqdn = "foo.bar.local"
        proxy_list = {
            "*": "wildcard",
            "notlocal$": "proxy_no_match",
            "*.notbar.local$": "proxy_no_match",
        }
        self.assertEqual("wildcard", self.proxy_check(self.logger, fqdn, proxy_list))

    @patch("sys.__excepthook__")
    def test_237_handle_exception_keyboard_interrupt(self, mock_excepthook):
        """test handle_exception with KeyboardInterrupt - should call sys.__excepthook__"""
        exc_type = KeyboardInterrupt
        exc_value = KeyboardInterrupt("Test keyboard interrupt")
        exc_traceback = Mock()

        result = self.handle_exception(exc_type, exc_value, exc_traceback)

        # Verify that sys.__excepthook__ was called with correct parameters
        mock_excepthook.assert_called_once_with(exc_type, exc_value, exc_traceback)
        # Verify function returned None (early return)
        self.assertIsNone(result)

    @patch("logging.exception")
    def test_238_handle_exception_regular_exception(self, mock_logging_exception):
        """test handle_exception with regular exception - should call logging.exception"""
        exc_type = ValueError
        exc_value = ValueError("Test value error")
        exc_traceback = Mock()

        result = self.handle_exception(exc_type, exc_value, exc_traceback)

        # Verify that logging.exception was called with correct parameters
        mock_logging_exception.assert_called_once_with(
            "Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)
        )
        # Verify function returned None
        self.assertIsNone(result)

    @patch("logging.exception")
    def test_239_handle_exception_runtime_error(self, mock_logging_exception):
        """test handle_exception with RuntimeError - should call logging.exception"""
        exc_type = RuntimeError
        exc_value = RuntimeError("Test runtime error")
        exc_traceback = Mock()

        result = self.handle_exception(exc_type, exc_value, exc_traceback)

        # Verify that logging.exception was called
        mock_logging_exception.assert_called_once_with(
            "Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)
        )
        # Verify function returned None
        self.assertIsNone(result)

    @patch("logging.exception")
    def test_240_handle_exception_type_error(self, mock_logging_exception):
        """test handle_exception with TypeError - should call logging.exception"""
        exc_type = TypeError
        exc_value = TypeError("Test type error")
        exc_traceback = Mock()

        result = self.handle_exception(exc_type, exc_value, exc_traceback)

        # Verify that logging.exception was called
        mock_logging_exception.assert_called_once_with(
            "Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)
        )
        # Verify function returned None
        self.assertIsNone(result)

    @patch("sys.__excepthook__")
    @patch("logging.exception")
    def test_241_handle_exception_keyboard_interrupt_subclass(
        self, mock_logging_exception, mock_excepthook
    ):
        """test handle_exception with KeyboardInterrupt subclass - should call sys.__excepthook__"""

        # Create a subclass of KeyboardInterrupt
        class CustomKeyboardInterrupt(KeyboardInterrupt):
            pass

        exc_type = CustomKeyboardInterrupt
        exc_value = CustomKeyboardInterrupt("Custom keyboard interrupt")
        exc_traceback = Mock()

        result = self.handle_exception(exc_type, exc_value, exc_traceback)

        # Verify that sys.__excepthook__ was called (not logging.exception)
        mock_excepthook.assert_called_once_with(exc_type, exc_value, exc_traceback)
        mock_logging_exception.assert_not_called()
        # Verify function returned None
        self.assertIsNone(result)

    @patch("logging.exception")
    def test_242_handle_exception_system_exit(self, mock_logging_exception):
        """test handle_exception with SystemExit - should call logging.exception"""
        exc_type = SystemExit
        exc_value = SystemExit(1)
        exc_traceback = Mock()

        result = self.handle_exception(exc_type, exc_value, exc_traceback)

        # Verify that logging.exception was called (SystemExit is not KeyboardInterrupt)
        mock_logging_exception.assert_called_once_with(
            "Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)
        )
        # Verify function returned None
        self.assertIsNone(result)

    @patch("logging.exception")
    def test_243_handle_exception_custom_exception(self, mock_logging_exception):
        """test handle_exception with custom exception - should call logging.exception"""

        # Create a custom exception class
        class CustomException(Exception):
            pass

        exc_type = CustomException
        exc_value = CustomException("Custom exception message")
        exc_traceback = Mock()

        result = self.handle_exception(exc_type, exc_value, exc_traceback)

        # Verify that logging.exception was called
        mock_logging_exception.assert_called_once_with(
            "Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)
        )
        # Verify function returned None
        self.assertIsNone(result)

    def test_244_proxy_check(self):
        """check proxy - wildcard"""
        fqdn = "foo.bar.local"
        proxy_list = {"*.bar.local$": "proxy_match"}
        self.assertEqual("proxy_match", self.proxy_check(self.logger, fqdn, proxy_list))

    def test_245_ca_handler_load(self):
        """test ca_handler_load"""
        config_dic = {"foo": "bar"}
        self.assertFalse(self.ca_handler_load(self.logger, config_dic))

    def test_246_ca_handler_load(self):
        """test ca_handler_load"""
        config_dic = {"foo": "bar"}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.ca_handler_load(self.logger, config_dic))
        self.assertIn(
            "ERROR:test_a2c:CAhandler configuration missing in config file", lcm.output
        )

    @patch("importlib.import_module")
    def test_247_ca_handler_load(self, mock_imp):
        """test ca_handler_load"""
        config_dic = {"CAhandler": {"foo": "bar"}}
        mock_imp.side_effect = Exception("exc_mock_imp")
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.ca_handler_load(self.logger, config_dic))
        self.assertIn(
            "CRITICAL:test_a2c:Loading default CAhandler failed with err: exc_mock_imp",
            lcm.output,
        )

    @patch("importlib.import_module")
    def test_248_ca_handler_load(self, mock_imp):
        """test ca_handler_load"""
        config_dic = {"CAhandler": {"foo": "bar"}}
        mock_imp.return_value = "foo"
        self.assertEqual("foo", self.ca_handler_load(self.logger, config_dic))

    @patch("importlib.util")
    def test_249_ca_handler_load(self, mock_util):
        """test ca_handler_load"""
        config_dic = {"CAhandler": {"handler_file": "foo"}}
        mock_util.module_from_spec = Mock(return_value="foo")
        self.assertEqual("foo", self.ca_handler_load(self.logger, config_dic))

    @patch("importlib.import_module")
    @patch("importlib.util")
    def test_250_ca_handler_load(self, mock_util, mock_imp):
        """test ca_handler_load"""
        config_dic = {"CAhandler": {"handler_file": "foo"}}
        mock_util.module_from_spec.side_effect = Exception("exc_mock_util")
        mock_imp.return_value = "foo"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual("foo", self.ca_handler_load(self.logger, config_dic))
        self.assertIn(
            "CRITICAL:test_a2c:Loading CAhandler configured in cfg failed with err: exc_mock_util",
            lcm.output,
        )

    @patch("importlib.import_module")
    @patch("importlib.util")
    def test_251_ca_handler_load(self, mock_util, mock_imp):
        """test ca_handler_load"""
        config_dic = {"CAhandler": {"handler_file": "foo"}}
        mock_util.module_from_spec.side_effect = Exception("exc_mock_util")
        mock_imp.side_effect = Exception("exc_mock_imp")
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.ca_handler_load(self.logger, config_dic))
        self.assertIn(
            "CRITICAL:test_a2c:Loading default CAhandler failed with err: exc_mock_imp",
            lcm.output,
        )

    def test_252_eab_handler_load(self):
        """test eab_handler_load without EABhandler section"""
        config_dic = {"foo": "bar"}
        self.assertFalse(self.eab_handler_load(self.logger, config_dic))

    def test_253_eab_handler_load(self):
        """test eab_handler_load with incomplete EABhandler section"""
        config_dic = {"EABhandler": {"foo": "bar"}}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.eab_handler_load(self.logger, config_dic))
        self.assertIn(
            "WARNING:test_a2c:EABhandler section present but neither "
            "eab_handler_module nor eab_handler_file is set",
            lcm.output,
        )

    def test_254_eab_handler_load(self):
        """test eab_handler_load with incomplete EABhandler section returns None"""
        config_dic = {"EABhandler": {"foo": "bar"}}
        self.assertFalse(self.eab_handler_load(self.logger, config_dic))

    @patch("importlib.util")
    def test_255_eab_handler_load(self, mock_util):
        """test eab_handler_load"""
        config_dic = {"EABhandler": {"eab_handler_file": "foo"}}
        mock_util.module_from_spec = Mock(return_value="foo")
        self.assertEqual("foo", self.eab_handler_load(self.logger, config_dic))

    @patch("importlib.util")
    def test_256_eab_handler_load(self, mock_util):
        """test eab_handler_load when eab_handler_file load fails"""
        config_dic = {"EABhandler": {"eab_handler_file": "foo"}}
        mock_util.module_from_spec.side_effect = Exception("exc_mock_util")
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.eab_handler_load(self.logger, config_dic))
        self.assertIn(
            "CRITICAL:test_a2c:Loading EABhandler configured in cfg failed with err: exc_mock_util",
            lcm.output,
        )
        self.assertIn(
            "WARNING:test_a2c:EAB handler_file load failed",
            lcm.output,
        )

    @patch("importlib.util")
    def test_257_eab_handler_load(self, mock_util):
        """test eab_handler_load when eab_handler_file load fails returns None"""
        config_dic = {"EABhandler": {"eab_handler_file": "foo"}}
        mock_util.module_from_spec.side_effect = Exception("exc_mock_util")
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.eab_handler_load(self.logger, config_dic))
        self.assertIn(
            "CRITICAL:test_a2c:Loading EABhandler configured in cfg failed with err: exc_mock_util",
            lcm.output,
        )
        self.assertNotIn(
            "Loading default EABhandler failed",
            "".join(lcm.output),
        )

    def test_258_hooks_load(self):
        """test hooks load with empty config_dic"""
        config_dic = {}
        self.assertFalse(self.hooks_load(self.logger, config_dic))

    def test_259_hooks_load(self):
        """test hooks load with hooks but no hooks_file in config_dic"""
        config_dic = {"Hooks": {"foo": "bar"}}
        self.assertFalse(self.hooks_load(self.logger, config_dic))

    @patch("importlib.util")
    def test_260_hooks_load(self, mock_util):
        """test hooks load with hooks but no hooks_file in  config_dic"""
        config_dic = {"Hooks": {"hooks_file": "bar"}}
        mock_util.module_from_spec = Mock(return_value="foo")
        self.assertEqual("foo", self.hooks_load(self.logger, config_dic))
        self.assertTrue(mock_util.spec_from_file_location.called)
        self.assertTrue(mock_util.module_from_spec.called)

    @patch("importlib.util")
    def test_261_hooks_load(self, mock_util):
        """test hooks load with hooks but no hooks_file in  config_dic"""
        config_dic = {"Hooks": {"hooks_file": "bar"}}
        mock_util.module_from_spec = Exception("exc_mock_util")
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.hooks_load(self.logger, config_dic))
        self.assertIn(
            "CRITICAL:test_a2c:Loading Hooks configured in cfg failed with err: 'Exception' object is not callable",
            lcm.output,
        )

    @patch("importlib.import_module")
    def test_261b_ca_handler_load_module(self, mock_imp):
        """test ca_handler_load via handler_module"""
        config_dic = {"CAhandler": {"handler_module": "pkg.ca_handler"}}
        mock_imp.return_value = "mod"
        self.assertEqual("mod", self.ca_handler_load(self.logger, config_dic))
        mock_imp.assert_called_with("pkg.ca_handler")

    @patch("importlib.import_module")
    def test_261c_eab_handler_load_module(self, mock_imp):
        """test eab_handler_load via eab_handler_module"""
        config_dic = {"EABhandler": {"eab_handler_module": "pkg.eab_handler"}}
        mock_imp.return_value = "mod"
        self.assertEqual("mod", self.eab_handler_load(self.logger, config_dic))
        mock_imp.assert_called_with("pkg.eab_handler")

    @patch("importlib.import_module")
    def test_261d_hooks_load_module(self, mock_imp):
        """test hooks_load via hooks_module"""
        config_dic = {"Hooks": {"hooks_module": "pkg.hooks"}}
        mock_imp.return_value = "mod"
        self.assertEqual("mod", self.hooks_load(self.logger, config_dic))
        mock_imp.assert_called_with("pkg.hooks")

    @patch("importlib.util")
    def test_261e_ca_handler_load_file_deprecated(self, mock_util):
        """file-based CA handler load emits deprecation warning"""
        config_dic = {"CAhandler": {"handler_file": "foo"}}
        mock_util.module_from_spec = Mock(return_value="foo")
        with self.assertLogs("test_a2c", level="WARNING") as lcm:
            self.assertEqual("foo", self.ca_handler_load(self.logger, config_dic))
        self.assertTrue(
            any("handler_file is deprecated" in line for line in lcm.output)
        )

    @patch("importlib.import_module")
    @patch("importlib.util")
    def test_261f_ca_handler_module_preferred_over_file(self, mock_util, mock_imp):
        """handler_module takes precedence when both keys are set"""
        config_dic = {
            "CAhandler": {
                "handler_module": "pkg.ca_handler",
                "handler_file": "foo.py",
            }
        }
        mock_imp.return_value = "from_module"
        with self.assertLogs("test_a2c", level="WARNING") as lcm:
            self.assertEqual(
                "from_module", self.ca_handler_load(self.logger, config_dic)
            )
        self.assertFalse(mock_util.spec_from_file_location.called)
        self.assertTrue(any("ignoring handler_file" in line for line in lcm.output))

    def test_262_error_dic_get(self):
        """test error_dic_get"""
        result = {
            "accountdoesnotexist": "urn:ietf:params:acme:error:accountDoesNotExist",
            "alreadyrevoked": "urn:ietf:params:acme:error:alreadyRevoked",
            "badcsr": "urn:ietf:params:acme:error:badCSR",
            "badpubkey": "urn:ietf:params:acme:error:badPublicKey",
            "badrevocationreason": "urn:ietf:params:acme:error:badRevocationReason",
            "externalaccountrequired": "urn:ietf:params:acme:error:externalAccountRequired",
            "invalidcontact": "urn:ietf:params:acme:error:invalidContact",
            "invalidprofile": "urn:ietf:params:acme:error:invalidProfile",
            "malformed": "urn:ietf:params:acme:error:malformed",
            "ordernotready": "urn:ietf:params:acme:error:orderNotReady",
            "ratelimited": "urn:ietf:params:acme:error:rateLimited",
            "rejectedidentifier": "urn:ietf:params:acme:error:rejectedIdentifier",
            "serverinternal": "urn:ietf:params:acme:error:serverInternal",
            "unauthorized": "urn:ietf:params:acme:error:unauthorized",
            "unsupportedidentifier": "urn:ietf:params:acme:error:unsupportedIdentifier",
            "useractionrequired": "urn:ietf:params:acme:error:userActionRequired",
        }
        self.assertEqual(result, self.error_dic_get(self.logger))

    def test_263_logger_nonce_modify(self):
        """test _logger_nonce_modify()"""
        data_dic = {"foo": "bar"}
        self.assertEqual({"foo": "bar"}, self.logger_nonce_modify(data_dic))

    def test_264_logger_nonce_modify(self):
        """test _logger_nonce_modify()"""
        data_dic = {"foo": "bar", "header": {"foo": "bar"}}
        self.assertEqual(
            {"foo": "bar", "header": {"foo": "bar"}}, self.logger_nonce_modify(data_dic)
        )

    def test_265_logger_nonce_modify(self):
        """test _logger_nonce_modify()"""
        data_dic = {"foo": "bar", "header": {"Replay-Nonce": "bar"}}
        self.assertEqual(
            {"foo": "bar", "header": {"Replay-Nonce": "- modified -"}},
            self.logger_nonce_modify(data_dic),
        )

    def test_266_logger_certificate_modify(self):
        """test _logger_certificate_modify()"""
        data_dic = {"data": "bar"}
        self.assertEqual(
            {"data": "bar"}, self.logger_certificate_modify(data_dic, "locator")
        )

    def test_267_logger_certificate_modify(self):
        """test _logger_certificate_modify()"""
        data_dic = {"data": "bar"}
        self.assertEqual(
            {"data": " - certificate - "},
            self.logger_certificate_modify(data_dic, "foo/acme/cert"),
        )

    def test_268_logger_token_modify(self):
        """test _logger_token_modify()"""
        data_dic = {"data": "bar"}
        self.assertEqual({"data": "bar"}, self.logger_token_modify(data_dic))

    def test_269_logger_token_modify(self):
        """test _logger_token_modify()"""
        data_dic = {"data": {"token": "token"}}
        self.assertEqual(
            {"data": {"token": "- modified -"}}, self.logger_token_modify(data_dic)
        )

    def test_270_logger_challenges_modify(self):
        """test _logger_challenges_modify()"""
        data_dic = {"data": "bar"}
        self.assertEqual({"data": "bar"}, self.logger_challenges_modify(data_dic))

    def test_271_logger_challenges_modify(self):
        """test _logger_challenges_modify()"""
        data_dic = {"data": {"challenges": [{"token": "token1"}]}}
        self.assertEqual(
            {"data": {"challenges": [{"token": "- modified - "}]}},
            self.logger_challenges_modify(data_dic),
        )

    def test_272_logger_challenges_modify(self):
        """test _logger_challenges_modify()"""
        data_dic = {"data": {"challenges": [{"token": "token1"}, {"token": "token2"}]}}
        self.assertEqual(
            {
                "data": {
                    "challenges": [
                        {"token": "- modified - "},
                        {"token": "- modified - "},
                    ]
                }
            },
            self.logger_challenges_modify(data_dic),
        )

    def test_273_config_check(self):
        """test config check"""
        config_dic = {"foo": {"bar": '"foobar"'}}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.config_check(self.logger, config_dic)
        self.assertIn(
            'WARNING:test_a2c:Section foo option: bar contains " characters. Please check if this is required!',
            lcm.output,
        )

    def test_274_helper_cert_cn_get(self):
        """get cn of csr"""
        cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u
                ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw
                FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
                ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq
                HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC
                7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y
                dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er
                1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+
                FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z
                zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7
                LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB
                AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02
                5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm
                TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h
                bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR
                fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H
                t+eRUDECE+0UnjyeCjTn3EU="""
        self.assertEqual("foo.example.com", self.cert_cn_get(self.logger, cert))

    def test_275_logger_challenges_modify(self):
        """test string_sanitize()"""
        unsafe_string = "foo"
        self.assertEqual("foo", self.string_sanitize(self.logger, unsafe_string))

    def test_276_logger_challenges_modify(self):
        """test string_sanitize()"""
        unsafe_string = "foo\n;"
        self.assertEqual("foo;", self.string_sanitize(self.logger, unsafe_string))

    def test_277_logger_challenges_modify(self):
        """test string_sanitize()"""
        unsafe_string = "fooö"
        self.assertEqual("foo", self.string_sanitize(self.logger, unsafe_string))

    def test_278_logger_challenges_modify(self):
        """test string_sanitize()"""
        unsafe_string = "fooö"
        self.assertEqual("foo", self.string_sanitize(self.logger, unsafe_string))

    def test_279_logger_challenges_modify(self):
        """test string_sanitize()"""
        unsafe_string = "foo    "
        self.assertEqual("foo ", self.string_sanitize(self.logger, unsafe_string))

    def test_280_logger_challenges_modify(self):
        """test string_sanitize()"""
        unsafe_string = "foo\u0009"
        self.assertEqual("foo ", self.string_sanitize(self.logger, unsafe_string))

    def test_281_pembundle_to_list(self):
        """bundle to list"""
        pembundle_to_list = "foo"
        self.assertFalse(self.pembundle_to_list(self.logger, pembundle_to_list))

    def test_282_pembundle_to_list(self):
        """bundle to list"""
        pembundle_to_list = "-----BEGIN CERTIFICATE-----foo"
        self.assertEqual(
            ["-----BEGIN CERTIFICATE-----foo\n"],
            self.pembundle_to_list(self.logger, pembundle_to_list),
        )

    def test_283_pembundle_to_list(self):
        """bundle to list"""
        pembundle_to_list = (
            "-----BEGIN CERTIFICATE-----foo\n-----BEGIN CERTIFICATE-----foo1"
        )
        self.assertEqual(
            ["-----BEGIN CERTIFICATE-----foo\n", "-----BEGIN CERTIFICATE-----foo1\n"],
            self.pembundle_to_list(self.logger, pembundle_to_list),
        )

    def test_284_certid_check(self):
        """test certid_check"""
        certid = "e181efbe6f7ae3ea71c78fc99e4226d7185715be3d289eaa56801dff4696ca4d0420ae0dcf53345691826b81d093e9c7588c35dd5ec5eacf5b1b2606330515d5faf402082cca85f640d54142"
        renewal_info = "MFswCwYJYIZIAWUDBAIBBCDhge--b3rj6nHHj8meQibXGFcVvj0onqpWgB3_RpbKTQQgrg3PUzRWkYJrgdCT6cdYjDXdXsXqz1sbJgYzBRXV-vQCCCzKhfZA1UFC"
        self.assertTrue(self.certid_check(self.logger, renewal_info, certid))

    def test_285_certid_check(self):
        """test certid_check"""
        certid = "false"
        renewal_info = "MFswCwYJYIZIAWUDBAIBBCDhge--b3rj6nHHj8meQibXGFcVvj0onqpWgB3_RpbKTQQgrg3PUzRWkYJrgdCT6cdYjDXdXsXqz1sbJgYzBRXV-vQCCCzKhfZA1UFC"
        self.assertFalse(self.certid_check(self.logger, renewal_info, certid))

    def test_286_certid_asn1_get(self):
        """test certid_asn1_get()"""

        cert_pem = """-----BEGIN CERTIFICATE-----
MIIDijCCAXKgAwIBAgIILMqF9kDVQUIwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE
CxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMzA3MDMwNTA5
NDVaFw0yNDA3MDIwNTA5NDVaMBsxGTAXBgNVBAMTEGxlZ28tMS5iYXIubG9jYWww
WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQDmn49aWZb/mRghkT3rgpkV45c5PbE
LFgQSh2qT7AHEmOv+8SNSjAbgysgJDqXMte4nUQOtYeKEZiy8xaD5ymho4GNMIGK
MB0GA1UdDgQWBBS5fAkcGAyo4okkZxEeGgLqmLo3izAfBgNVHSMEGDAWgBS/3o6O
BiIiq61DyN3UT6irSEE+1TALBgNVHQ8EBAMCA+gwDAYDVR0TAQH/BAIwADAtBgNV
HREEJjAkghBsZWdvLTEuYmFyLmxvY2FsghBsZWdvLTIuYmFyLmxvY2FsMA0GCSqG
SIb3DQEBCwUAA4ICAQAAYE1U/IR6XRbjnRT9jzit/biRJDFGT7JMfD14pUpXU7ax
IfndaWA8y0UQ0ZyIiLke+chHWQ2CrYT7wUMjSp08ztViWXDg0IifW4Hcyqx/oNT0
pCaQeRHJOM17ai9oWZEaJMY/r0/1fCTAK7D0zrJxHCQqEXuosm9LJd0fRMamgGZC
bXN/HrVOGojOLwzE1mMyW261hI5eU7/DD128iyc0mfeCi2R3lL7oXcwN7MtrKUYq
qpBEfMlrf07zpAGVe/LOB6SLoPCbjYPC368mwdxgGLLz2+nqPTK2V+2yjylt3de5
LVp6UG3ZxLNN2RjVXCE7Bh1fT585+NzaaXpf4SWyDxu11yHdfXP5Nw5paELjyNhM
V9lnEJUiLB4scO1p4XWOQDboLXf0RbI0M/0IxqRZzzKxDRXsnIzdQOswxv8Jfnli
r0yVc/vzYQeKEkKkRwRw2SVTj9v4lU+ryMrqMCpw/z6vRBLKWAg8cmGE2OTtcL91
QvJeYpp+9g2GJxs+gEja3BlliLf6EUQkI/P/tCUoe3pEJ0XyPgl5m+5SdAS5Ic0U
qaUvBXcmU56/h8pzSCF2RDoGEpZyHaG84VJLCV857QD2NFlE/S+tUAggbc5l66OE
u3dZ8B+BJinV++0slP29NFdZ7m6ta0jZJfOaMXYyDwCYvD7FXygHu3fMwc5k3A==
-----END CERTIFICATE-----"""

        issuer_pem = """-----BEGIN CERTIFICATE-----
MIIFTzCCAzegAwIBAgIIAzHyhSyrXfMwDQYJKoZIhvcNAQELBQAwKzEXMBUGA1UE
CxMOYWNtZTJjZXJ0aWZpZXIxEDAOBgNVBAMTB3Jvb3QtY2EwHhcNMjAwNTI3MTM1
NDAwWhcNMzAwNTI2MjM1OTAwWjAqMRcwFQYDVQQLEw5hY21lMmNlcnRpZmllcjEP
MA0GA1UEAxMGc3ViLWNhMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
xXHaGZsolXe+PBdUryngHP9VbBC1mehqeTtYI+hqsqGNH7q9a7bSrxMwFuF1kYL8
jqqxkJdtl0L94xcxJg/ZdMx7Nt0vGI+BaAuTpEpUEHeN4tqS6NhB/m/0LGkAELc/
qkzmoO4B1FDwEEj/3IXtZcupqG80oDt7jWSGXdtF7NTjzcumznMeRXidCdhxRxT/
/WrsChaytXo0xWZ56oeNwd6x6Dr8/39PBOWtj4fldyDcg+Q+alci2tx9pxmu2bCV
XcB9ftCLKhDk2WEHE88bgKSp7fV2RCmq9po+Tx8JJ7qecLunUsK/F0XN4kpoQLm9
hcymqchnMSncSiyin1dQHGHWgXDtBDdq6A2Z6rx26Qk5H9HTYvcNSe1YwFEDoGLB
ZQjbCPWiaqoaH4agBQTclPvrrSCRaVmhUSO+pBtSXDkmN4t3MDZxfgRkp8ixwkB1
5Y5f0LTpCyAJsdQDw8+Ea0aDqO30eskh4CErnm9+Fejd9Ew2cwpdwfBXzVSbYilM
GueQihZHvJmVRxAwU69aO2Qs8B0tQ60CfWKVlmWPiakrvYYlPp0FBsM61G6LZEN8
hH2CKnS8hHv5IWEXZvp0Pk8V3P5h6bWN0Tl+x/V1Prt7Wp8NoiPETE8XyDDxe6dm
KxztWBH/mTsJyMGb6ZiUoXdPU9TFUKqHxTRLHaxfsPsCAwEAAaN4MHYwEgYDVR0T
AQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUv96OjgYiIqutQ8jd1E+oq0hBPtUwDgYD
VR0PAQH/BAQDAgGGMBEGCWCGSAGG+EIBAQQEAwIABzAeBglghkgBhvhCAQ0EERYP
eGNhIGNlcnRpZmljYXRlMA0GCSqGSIb3DQEBCwUAA4ICAQBbHLEVyg4f9uEujroc
31UVyDRLMdPgEPLjOenSBCBmH0N81whDmxNI/7JAAB6J14WMX8OLF0HkZnb7G77W
vDhy1aFvQFbXHBz3/zUO9Mw9J4L2XEW6ond3Nsh1m2oXeBde3R3ANxuIzHqZDlP9
6YrRcHjnf4+1/5AKDJAvJD+gFb5YnYUKH2iSvHUvG17xcZx98Rf2eo8LealG4JqH
Jh4sKRy0VjDQD7jXSCbweTHEb8wz+6OfNGrIo+BhTFP5vPcwE4nlJwYBoaOJ5cVa
7gdQJ7WkLSxvwHxuxzvSVK73u3jl3I9SqTrbMLG/jeJyV0P8EvdljOaGnCtQVRwC
zM4ptXUvKhKOHy7/nyTF/Bc35ZwwL/2xWvNK1+NibgE/6CFxupwWpdmxQbVVuoQ3
2tUil9ty0yC6m5GKE8+t1lrZuxyA+b/TBnYNO5xo8UEMbkpxaNYSwmw+f/loxXP/
M7sIBcLvy2ugHEBxwd9o/kLXeXT2DaRvxPjp4yk8MpJRpNmz3aB5HJwaUnaRLVo5
Z3XWWXmjMGZ6/m0AAoDbDz/pXtOoJZT8BJdD1DuDdszVsQnLVn4B/LtIXL6FbXsF
zfv6ERP9a5gpKUZ+4NjgrnlGtdccNZpwyWF0IXcvaq3b8hXIRO4hMjzHeHfzJN4t
jX1vlY35Ofonc4+6dRVamBiF9A==
-----END CERTIFICATE-----"""
        result = "e181efbe6f7ae3ea71c78fc99e4226d7185715be3d289eaa56801dff4696ca4d0420ae0dcf53345691826b81d093e9c7588c35dd5ec5eacf5b1b2606330515d5faf402082cca85f640d54142"
        self.assertEqual(
            result, self.certid_asn1_get(self.logger, cert_pem, issuer_pem)
        )

    def test_287_certid_hex_get(self):
        """test certid_check"""
        certid = "false"
        renewal_info = "MFswCwYJYIZIAWUDBAIBBCDhge--b3rj6nHHj8meQibXGFcVvj0onqpWgB3_RpbKTQQgrg3PUzRWkYJrgdCT6cdYjDXdXsXqz1sbJgYzBRXV-vQCCCzKhfZA1UFC"
        self.assertEqual(
            (
                "300b0609608648016503040201",
                "e181efbe6f7ae3ea71c78fc99e4226d7185715be3d289eaa56801dff4696ca4d0420ae0dcf53345691826b81d093e9c7588c35dd5ec5eacf5b1b2606330515d5faf402082cca85f640d54142",
            ),
            self.certid_hex_get(self.logger, renewal_info),
        )

    @patch("acme2certifier.acme_srv.helpers.network.USER_AGENT", "FOOBAR")
    def test_288_v6_adjust(self):
        """test v6_adjust()"""
        url = "http://www.foo.bar"
        self.assertEqual(
            (
                {
                    "Connection": "close",
                    "Accept-Encoding": "gzip",
                    "User-Agent": "FOOBAR",
                },
                "http://www.foo.bar",
            ),
            self.v6_adjust(self.logger, url),
        )

    @patch("acme2certifier.acme_srv.helpers.network.USER_AGENT", "FOOBAR")
    def test_289_v6_adjust(self):
        """test v6_adjust()"""
        url = "http://192.168.123.10"
        self.assertEqual(
            (
                {
                    "Connection": "close",
                    "Accept-Encoding": "gzip",
                    "User-Agent": "FOOBAR",
                },
                "http://192.168.123.10",
            ),
            self.v6_adjust(self.logger, url),
        )

    @patch("acme2certifier.acme_srv.helpers.network.USER_AGENT", "FOOBAR")
    def test_290_v6_adjust(self):
        """test v6_adjust()"""
        url = "http://fe80::215:5dff:fec0:102"
        self.assertEqual(
            (
                {
                    "Connection": "close",
                    "Accept-Encoding": "gzip",
                    "User-Agent": "FOOBAR",
                    "Host": "fe80::215:5dff:fec0:102",
                },
                "http://[fe80::215:5dff:fec0:102]/",
            ),
            self.v6_adjust(self.logger, url),
        )

    def test_291_ipv6_chk(self):
        """test ipv6_chk()"""
        addr_obj = "fe80::215:5dff:fec0:102"
        self.assertTrue(self.ipv6_chk(self.logger, addr_obj))

    def test_292_ipv6_chk(self):
        """test ipv6_chk()"""
        addr_obj = "foo.bar.local"
        self.assertFalse(self.ipv6_chk(self.logger, addr_obj))

    def test_293_ipv6_chk(self):
        """test ipv6_chk()"""
        addr_obj = "192.168.123.10"
        self.assertFalse(self.ipv6_chk(self.logger, addr_obj))

    def test_294_ipv6_chk(self):
        """test ipv6_chk()"""
        addr_obj = None
        self.assertFalse(self.ipv6_chk(self.logger, addr_obj))

    def test_295_header_info_get(self):
        """header_info_get ()"""
        models_mock = MagicMock()
        models_mock.DBstore().certificates_search.return_value = ("foo", "bar")
        modules = {"acme2certifier.acme_srv.db_handler": models_mock}
        patch.dict("sys.modules", modules).start()
        self.assertEqual(["foo", "bar"], self.header_info_get(self.logger, "csr"))

    def test_296_header_info_get(self):
        """header_info_get ()"""
        models_mock = MagicMock()
        models_mock.DBstore().certificates_search.side_effect = Exception("mock_search")
        modules = {"acme2certifier.acme_srv.db_handler": models_mock}
        patch.dict("sys.modules", modules).start()
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.header_info_get(self.logger, "csr"))
        self.assertIn(
            "ERROR:test_a2c:Error while getting header_info from database: mock_search",
            lcm.output,
        )

    def test_297_encode_url(self):
        # Test with a simple URL
        url = "www.example.com"
        self.assertEqual(url, self.encode_url(self.logger, url))

    def test_298_encode_url(self):
        # Test with a URL containing spaces
        url = "www.example.com/hello world"
        self.assertEqual(
            "www.example.com/hello%20world", self.encode_url(self.logger, url)
        )

    def test_299_encode_url(self):
        # Test with a URL containing special characters
        url = "www.example.com/hello@world?foo=bar&bar=foo"
        self.assertEqual(
            "www.example.com/hello%40world%3Ffoo%3Dbar%26bar%3Dfoo",
            self.encode_url(self.logger, url),
        )

    def test_300_uts_now(self):
        """test uts_now()"""
        self.assertIsInstance(self.uts_now(), int)

    def test_301_ip_validate(self):
        """test ip validate"""
        self.assertEqual(
            ("1.0.0.10.in-addr.arpa", False), self.ip_validate(self.logger, "10.0.0.1")
        )

    def test_302_ip_validate(self):
        """test ip validate"""
        self.assertEqual((None, True), self.ip_validate(self.logger, "1000.0.0.1"))

    def test_303_cert_ski_get(self):
        """test cert_san_get for a multiple SAN of type DNS"""
        cert = """MIIDIzCCAgugAwIBAgICBZgwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAxMPZm9v
                LmV4YW1wbGUuY29tMB4XDTE5MDEyMDE3MDkxMVoXDTE5MDIxOTE3MDkxMVowGjEY
                MBYGA1UEAxMPZm9vLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
                MIIBCgKCAQEA+EM+gzAyjegQSRbJI+qZJhuAGM9i48xvIfuOQHleXoJPjV+8VZRV
                KDljZNXdNT5Zi7K6HY9C622NOV7QefB6zTtm6mSY08ypNsaeorhIvJdnpaJ9gAGH
                YeQqJ04fL099kiRXJAv8gT8wdpiekg2KEU4wlXMIRfSHiiB37yjcqUzXl6XYYKGe
                2USMpDfliXL3o8TW2KByGUdCzXUdNbMgzRXwYxkX2+xV2f0vn8NyXHiHg9yJRof2
                HTjyvAcXN5Nr987slq/Ex5lXLtpB861Ov3ZbwxyzREjmreZBlze7KTfP5IY66XuN
                Mvhi7AAs0cLTd3SNjpppE/yvUi5q5gfhXQIDAQABo3MwcTAfBgNVHSMEGDAWgBSl
                YnpKQw12MmEMpvsTEeQi17UsnDAdBgNVHQ4EFgQUpWJ6SkMNdjJhDKb7ExHkIte1
                LJwwLwYDVR0RBCgwJoIRZm9vLTIuZXhhbXBsZS5jb22CEWZvby0xLmV4YW1wbGUu
                Y29tMA0GCSqGSIb3DQEBCwUAA4IBAQASA20TtMPXIHH10dikLhFuI14EOtZzXvCx
                kGlJw9/5JuvVKLsL1wd8BC9o/lg8apDqsrDZ/+0Nc8g3Z9HRN99vcLsVDdT27DkM
                BslfXdN/qBhKAp3m7jw29uijX5fss+Wz9iHfHciUjVyMJ4DoFxHYPbMWQG8XEUKR
                TP6Gp79DzCiPKFt52Y8yVikIET4fnyRzU8kGKLuPoIt+EQQzpG26qWAjeNHAASEM
                keiA+tedMWzydX52B+tGg+l2svxg34apIBDjK8pF+8ZxTt5yjVUa10GbpffJuiEh
                NWQddOR8IHg+v6lWc9BtuuKK5ubsg6XOiEjhhr42AKViKalX1i4+"""
        self.assertEqual(
            "a5627a4a430d7632610ca6fb1311e422d7b52c9c",
            self.cert_ski_get(self.logger, cert),
        )

    def test_304_cert_aki_get(self):
        """test cert_san_get aki"""
        cert = "MIIEOzCCAiOgAwIBAgIIKndYX0qdb04wDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yNDAxMjkyMDA0NTZaFw0yNTAxMjgyMDA0NTZaMD8xFzAVBgNVBAMTDmxlZ28uYmFyLmxvY2FsMRcwFQYDVQQKDA5hY21lMmNlcnRpZmllcjELMAkGA1UEBhMCREUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQKIqEIxeS0JIN+iqsJ+08IJFFmuvfpjFnH4wFD2OLlmeTvfpDsnD00uw/orLvecDvjt48JvgYR8Wv+9C4ajIDfo4IBGTCCARUwHQYDVR0OBBYEFCka80MPgj45/quHJ9oF8Cc1YlsXMB8GA1UdIwQYMBaAFL/ejo4GIiKrrUPI3dRPqKtIQT7VMAsGA1UdDwQEAwID6DBRBgNVHSUBAf8ERzBFBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgGCCsGAQUFBwMJBgcrBgEFAgMFMEoGA1UdHwRDMEEwHqAcoBqGGFVSSTpodHRwOi8vZm9vLmJhci5sb2NhbDAfoB2gG4YZVVJJOmh0dHA6Ly9mb28xLmJhci5sb2NhbDAMBgNVHRMBAf8EAjAAMBkGA1UdEQQSMBCCDmxlZ28uYmFyLmxvY2FsMA0GCSqGSIb3DQEBCwUAA4ICAQB4FxJwQ/aILMzh7jBSr358RA92mX8srPmzQrjPYoU7T2LxwMf+eb0z5x0PMFH8j5FgRvRGWo6rcco8rL+B+gvrVhQ0TfAFEF77WJfKG2XMlnEN/9Ri73J7+dA45kaw8CZRSfUBpIW6fb4N+6frXyIKwBaZnrT6qiy+Izu+ZH6RkaTFrBn5yOWvVyk7aBHE1eZ+3+eA3qBI4UPaeYFSwr3gY5dxfbPktlFgvpCI22ff4NAb/fzjAQsKRTkXkOVqAvBJcWI5d/g32IVMLq0ub13XLe+yHk0iCxyMaIRdN4+W6RYi3gvtTQh6LaOjncWDYLdsm+vN+YqXEqieY5TC1oC8kG9We9eHzKHdNquJnrju536DPqh4xYEDcb+PGvTr3sqYdSikA9v5FuWUGeiZD/ZEvw/p7F7DevD5NO1JaOtfWDwDwxFHEyn+iwTVq3QDEc4j+oyGnQJs5Spoyz3tJi31VMJk+EAKKUV66aVNynLM7Ce4Oj0M67o4pcnDd0uWBMSAg4lH8KIX0IsmMfLnirIqOOwrZ4UkPKlEjD+oZQf5IBukfdHob/bo4fW8q4eU/I8z9w3BTdV1yNVH/ANHg5AItoPabkr65oBTwY51j3FVq0gK+4xVrevcyIeY3A9XFzA18k/gX7O/kf/IrM0dcZWJnsW39byiWhUd4JetJaGeKg"
        self.assertEqual(
            "bfde8e8e062222abad43c8ddd44fa8ab48413ed5",
            self.cert_aki_get(self.logger, cert),
        )

    def test_305_cert_aki_get_error_handling(self):
        """test cert_aki_get() error handling when AKI is missing"""
        # Use a valid PEM certificate without AKI extension (from other tests)
        cert = """MIIEHDCCAgSgAwIBAgIPAZ4wdJfqm1tO+Fh4RIFBMA0GCSqGSIb3DQEBDQUAMBkxFzAVBgNVBAMTDk5ldyBSU0EgU3ViIENBMB4XDTI2MDUxNjEwMzMyN1oXDTI3MDUxNjExMDMyN1owFzEVMBMGA1UEAxMMYWNtZS1zaC5hY21lMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqgZcTr/0DMZILNilvYPCDKMd7IGA6jpFuXvjQiF/tSkk+rR2ulkMee7SBI6dBfGqulthwSVPBYIaOOCCBwoFUotvOqp2VWFeeq/M7hrE/2Ld0oydvN0Bnngtrq0IjM+cZOaupg3vJhsUL/BZqQ4XkEzPf9ydo4fuhkD4rFkaaz6ZTCTjJX4YvD2zsIydfiNVp6+hr6iPdJdYfHJebtIh1tg6fEkZH5heoZTKWm2b2W3ZVeMSzDr/gI0SQA6On1WY56/cXetbcLnGR3UFFUhw6RAT6/tL1lt8NbLjVrpl0ibAgPdealMVuwYE54+DUzIto0PWKJpfz9ThVlashppuUwIDAQABo2MwYTAfBgNVHSMEGDAWgBSryf/9VmQhFktiIG28gA+6hGdlmjAdBgNVHQ4EFgQUzCvWZddDuFyxFbPbv6AzgFu2eYUwDgYDVR0PAQH/BAQDAgQwMA8GA1UdEwEB/wQFMAMBAQAwDQYJKoZIhvcNAQENBQADggIBALUZcRH4Cnz4VxvnINV1Homb9HbtaOp4Iq6ehLf281e8AL9jchRoraMOXWOwxrCjvgYf59GPlYpRh4j9EoiQdJkSdJrHME2h5XdG/y05TgNcYB0IefdccDQTlkbibb5MdbM14oGBjP1EgDa6+UHdybXEIHLTxmxqR3hAPjXzbiijibrIhpUOOdL8cLrxYI87IuQWm3OYWuBqMFVCsH8aSHAfwfcVWFtEPL2f9goyvTlzy2k+lGF1PHokHBRucFeg1qfEhbXU4qI8k6MdOAmgxFk7At+Ah6r8V6eVPu+MR+uQUTd7t0Gkp15A48Iezj09WaCEayKg1gzV5X1Jdgv7q/98TvzrEe9gCFdV2z/UmBaXDfkPqd2x4Fl/Bqsb+Ajprt+5XEcBzlpGjhHGVGvk3kjy/PHbnviwjQrTApA7XJDUF055/HPOfFO7WPnFsOgE2Oi5i7u911IAU1ZVy8WdAgkmGZFWL/cECZaidkDaoSWVfjdavr6UkmEuQOv4FjB+QrFn0ESMuaRJdolsI0UYN+3kxXphBYxTcnzWyzUEaylkMt3a7pGsBcyrGldpMQ4TKok1braRQiL0M6MtpEVRkXJC/nMFeQAub++9GTzLh7Deu9iX0GRZBLLlhwfKpcHuJ8TYbpew3ZRDe6GVNmEZ/n5Bq8118hjzHr1N5FOv2XqU"""
        aki = self.cert_aki_get(self.logger, cert)
        self.assertEqual(aki, "abc9fffd566421164b62206dbc800fba8467659a")

    @patch("acme2certifier.acme_srv.helpers.certificates._cert_ski_pyopenssl_get")
    @patch("acme2certifier.acme_srv.helpers.certificates.x509.Certificate.extensions")
    def test_306_cert_ski_get_error_handling(self, mock_ext, mock_ski_get):
        """test cert_ski_get() error handling when SKI is missing"""
        cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u
    ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw
    FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
    ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq
    HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC
    7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y
    dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er
    1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+
    FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z
    zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7
    LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB
    AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02
    5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm
    TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h
    bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR
    fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H
    t+eRUDECE+0UnjyeCjTn3EU="""
        mock_ext.get_extension_for_oid.side_effect = Exception("No SKI")
        mock_ski_get.return_value = "pyopenssl"
        ski = self.cert_ski_get(self.logger, cert)
        self.assertEqual(ski, "pyopenssl")

    def test_307_validate_fqdn(self):
        """test validate_fqdn()"""
        self.assertTrue(self.validate_fqdn(self.logger, "foo.bar.com"))

    def test_308_validate_fqdn(self):
        """test validate_fqdn()"""
        self.assertFalse(self.validate_fqdn(self.logger, "-foo.bar.com"))

    def test_309_validate_fqdn(self):
        """test validate_fqdn()"""
        self.assertFalse(self.validate_fqdn(self.logger, "foo.bar.com/foo"))

    def test_310_validate_fqdn(self):
        """test validate_fqdn()"""
        self.assertFalse(self.validate_fqdn(self.logger, "foo.bar.com#foo"))

    def test_311_validate_fqdn(self):
        """test validate_fqdn()"""
        self.assertFalse(self.validate_fqdn(self.logger, "foo.bar.com?foo=foo"))

    def test_312_validate_fqdn(self):
        """test validate_fqdn()"""
        self.assertFalse(
            self.validate_fqdn(self.logger, "2a01:c22:b0cf:600:74be:80a7:4feb:bfe8")
        )

    def test_313_validate_fqdn(self):
        """test validate_fqdn()"""
        self.assertFalse(self.validate_fqdn(self.logger, "foo.bar.com:8080"))

    def test_314_validate_fqdn(self):
        """test validate_fqdn()"""
        self.assertFalse(self.validate_fqdn(self.logger, "foo@bar.local"))

    def test_315_validate_fqdn(self):
        """test validate_fqdn()"""
        self.assertTrue(self.validate_fqdn(self.logger, "*.bar.local"))

    def test_316_validate_ip(self):
        """test validate_ip()"""
        self.assertTrue(self.validate_ip(self.logger, "10.0.0.1"))

    def test_317_validate_ip(self):
        """test validate_ip()"""
        self.assertTrue(
            self.validate_ip(self.logger, "2a01:c22:b0cf:600:74be:80a7:4feb:bfe8")
        )

    def test_318_validate_ip(self):
        """test validate_ip()"""
        self.assertFalse(self.validate_ip(self.logger, "foo.bar.local"))

    def test_319_validate_ip(self):
        """test validate_ip()"""
        self.assertFalse(self.validate_ip(self.logger, "foo@bar.local"))

    def test_320_validate_ip(self):
        """test validate_ip()"""
        self.assertFalse(self.validate_ip(self.logger, "301.0.0.1"))

    @patch("acme2certifier.acme_srv.helpers.validation.validate_email")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_fqdn")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_ip")
    def test_321_validate_identifier(self, mock_ip, mock_fqdn, mock_email):
        """test validate_identifier"""
        mock_fqdn.return_value = "dns"
        mock_ip.return_value = "ip"
        self.assertEqual(
            "dns", self.validate_identifier(self.logger, "dns", "foo.bar.com")
        )
        self.assertTrue(mock_fqdn.called)
        self.assertFalse(mock_ip.called)
        self.assertFalse(mock_email.called)

    @patch("acme2certifier.acme_srv.helpers.validation.validate_email")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_fqdn")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_ip")
    def test_322_validate_identifier(self, mock_ip, mock_fqdn, mock_email):
        """test validate_identifier"""
        mock_fqdn.return_value = "dns"
        mock_ip.return_value = "ip"
        self.assertEqual("ip", self.validate_identifier(self.logger, "ip", "ip"))
        self.assertFalse(mock_fqdn.called)
        self.assertTrue(mock_ip.called)
        self.assertFalse(mock_email.called)

    @patch("acme2certifier.acme_srv.helpers.validation.validate_email")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_fqdn")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_ip")
    def test_323_validate_identifier(self, mock_ip, mock_fqdn, mock_email):
        """test validate_identifier"""
        mock_fqdn.return_value = "dns"
        mock_ip.return_value = "ip"
        self.assertFalse(self.validate_identifier(self.logger, "unk", "ip"))
        self.assertFalse(mock_fqdn.called)
        self.assertFalse(mock_ip.called)
        self.assertFalse(mock_email.called)

    @patch("acme2certifier.acme_srv.helpers.validation.validate_email")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_fqdn")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_ip")
    def test_324_validate_identifier(self, mock_ip, mock_fqdn, mock_email):
        """test validate_identifier"""
        mock_fqdn.return_value = "dns"
        mock_ip.return_value = "ip"
        self.assertFalse(self.validate_identifier(self.logger, "tnauthlist", "ip"))
        self.assertFalse(mock_fqdn.called)
        self.assertFalse(mock_ip.called)
        self.assertFalse(mock_email.called)

    @patch("acme2certifier.acme_srv.helpers.validation.validate_email")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_fqdn")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_ip")
    def test_325_validate_identifier(self, mock_ip, mock_fqdn, mock_email):
        """test validate_identifier"""
        mock_fqdn.return_value = "dns"
        mock_ip.return_value = "ip"
        self.assertTrue(self.validate_identifier(self.logger, "tnauthlist", "ip", True))
        self.assertFalse(mock_fqdn.called)
        self.assertFalse(mock_ip.called)
        self.assertFalse(mock_email.called)

    @patch("acme2certifier.acme_srv.helpers.validation.validate_email")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_fqdn")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_ip")
    def test_326_validate_identifier(self, mock_ip, mock_fqdn, mock_email):
        """test validate_identifier"""
        mock_fqdn.return_value = "dns"
        mock_ip.return_value = "ip"
        self.assertTrue(self.validate_identifier(self.logger, "email", "email", True))
        self.assertFalse(mock_fqdn.called)
        self.assertFalse(mock_ip.called)
        self.assertTrue(mock_email.called)

    @patch("acme2certifier.acme_srv.helpers.config.profile_lookup")
    @patch("acme2certifier.acme_srv.helpers.config.header_info_lookup")
    def test_327_client_parameter_validate(self, mock_lookup, mock_profile):
        """test client_parameter_validate"""
        mock_lookup.return_value = "value2"
        mock_profile.return_value = "value1"
        cahandler = FakeDBStore()
        cahandler.profiles = {"foo": "bar"}
        self.assertEqual(
            ("value1", None),
            self.client_parameter_validate(
                self.logger, "csr", cahandler, "key", ["value0", "value1", "value2"]
            ),
        )
        self.assertFalse(mock_lookup.called)
        self.assertTrue(mock_profile.called)

    @patch("acme2certifier.acme_srv.helpers.config.profile_lookup")
    @patch("acme2certifier.acme_srv.helpers.config.header_info_lookup")
    def test_328_client_parameter_validate(self, mock_lookup, mock_profile):
        """test client_parameter_validate"""
        mock_lookup.return_value = "value2"
        cahandler = FakeDBStore()
        self.assertEqual(
            ("value2", None),
            self.client_parameter_validate(
                self.logger, "csr", cahandler, "key", ["value0", "value2"]
            ),
        )
        self.assertTrue(mock_lookup.called)
        self.assertFalse(mock_profile.called)

    @patch("acme2certifier.acme_srv.helpers.config.profile_lookup")
    @patch("acme2certifier.acme_srv.helpers.config.header_info_lookup")
    def test_329_client_parameter_validate(self, mock_lookup, mock_profile):
        """test client_parameter_validate"""
        mock_lookup.return_value = "unk_value"
        cahandler = FakeDBStore()
        self.assertEqual(
            (None, 'parameter "unk_value" is not allowed'),
            self.client_parameter_validate(
                self.logger,
                "csr",
                cahandler,
                "parameter",
                ["value0", "value2"],
            ),
        )
        self.assertTrue(mock_lookup.called)
        self.assertFalse(mock_profile.called)

    @patch("acme2certifier.acme_srv.helpers.config.profile_lookup")
    @patch("acme2certifier.acme_srv.helpers.config.header_info_lookup")
    def test_330_client_parameter_validate(self, mock_lookup, mock_profile):
        """test client_parameter_validate"""
        mock_lookup.return_value = None
        cahandler = FakeDBStore()
        self.assertEqual(
            ("value0", None),
            self.client_parameter_validate(
                self.logger,
                "csr",
                cahandler,
                "parameter",
                ["value0", "value2"],
            ),
        )
        self.assertTrue(mock_lookup.called)
        self.assertFalse(mock_profile.called)

    @patch("acme2certifier.acme_srv.helpers.network.header_info_get")
    def test_331_header_info_lookup(self, mock_info):
        """test header_info_lookup"""
        mock_info.return_value = [
            {"header_info": '{"header_info_field": "foo1=value1 foo2=value2"}'}
        ]
        self.assertEqual(
            "value1",
            self.header_info_lookup(self.logger, "csr", "header_info_field", "foo1"),
        )

    @patch("acme2certifier.acme_srv.helpers.network.header_info_get")
    def test_332_header_info_lookup(self, mock_info):
        """test header_info_lookup"""
        mock_info.return_value = [
            {"header_info": '{"header_info_field": "foo1=value1=foo foo2=value2=foo"}'}
        ]
        self.assertEqual(
            "value1=foo",
            self.header_info_lookup(self.logger, "csr", "header_info_field", "foo1"),
        )

    @patch("acme2certifier.acme_srv.helpers.network.header_info_get")
    def test_333_header_info_lookup(self, mock_info):
        """test header_info_lookup"""
        mock_info.return_value = None
        self.assertFalse(
            self.header_info_lookup(self.logger, "csr", "header_info_field", "foo1")
        )

    @patch("acme2certifier.acme_srv.helpers.network.header_info_get")
    def test_334_header_info_lookup(self, mock_info):
        """test header_info_lookup"""
        mock_info.return_value = [
            {"foo": '{"header_info_field": "foo1=value1 foo2=value2"}'}
        ]
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(
                self.header_info_lookup(self.logger, "csr", "header_info_field", "foo1")
            )
        self.assertIn(
            "WARNING:test_a2c:Header_info_field not found in header info: header_info_field",
            lcm.output,
        )

    @patch("acme2certifier.acme_srv.helpers.network.header_info_get")
    def test_335_header_info_lookup(self, mock_info):
        """test header_info_lookup"""
        mock_info.return_value = [{"header_info": '{"foo": "foo1=value1 foo2=value2"}'}]
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(
                self.header_info_lookup(self.logger, "csr", "header_info_field", "foo1")
            )
        self.assertIn(
            "WARNING:test_a2c:Header_info_field not found in header info: header_info_field",
            lcm.output,
        )

    @patch("acme2certifier.acme_srv.helpers.network.header_info_get")
    def test_336_header_info_lookup(self, mock_info):
        """test header_info_lookup"""
        mock_info.return_value = "bump"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(
                self.header_info_lookup(self.logger, "csr", "header_info_field", "foo1")
            )
        self.assertIn(
            "WARNING:test_a2c:Header_info_field not found in header info: header_info_field",
            lcm.output,
        )

    @patch("acme2certifier.acme_srv.helpers.config.json.loads")
    @patch("acme2certifier.acme_srv.helpers.network.header_info_get")
    def test_337_header_info_lookup(self, mock_info, mock_json):
        """test header_info_lookup"""
        mock_info.return_value = [{"header_info": "foo1=value1 foo2=value2"}]
        mock_json.side_effect = Exception("mock_json")
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(
                self.header_info_lookup(self.logger, "csr", "header_info_field", "foo1")
            )
        self.assertIn(
            "ERROR:test_a2c:Could not parse header_info_field: mock_json",
            lcm.output,
        )

    def test_338_config_headerinfo_load(self):
        """test config_headerinfo_load()"""
        config_dic = {"Order": {"header_info_list": '["foo", "bar", "foobar"]'}}
        self.assertEqual("foo", self.config_headerinfo_load(self.logger, config_dic))

    def test_339_config_headerinfo_load(self):
        """test config_headerinfo_load()"""
        config_dic = {"Order": {"header_info_list": '["foo"]'}}
        self.assertEqual("foo", self.config_headerinfo_load(self.logger, config_dic))

    def test_340_config_headerinfo_load(self):
        """test config_headerinfo_load()"""
        config_dic = {"Order": {"header_info_list": "foo"}}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.config_headerinfo_load(self.logger, config_dic))
        self.assertIn(
            "WARNING:test_a2c:Failed to parse header_info_list from configuration: Expecting value: line 1 column 1 (char 0)",
            lcm.output,
        )

    @patch("acme2certifier.acme_srv.helpers.config.eab_handler_load")
    def test_341_config_eab_profile_load(self, mock_eabload):
        """test config_eab_profiling()"""
        config_dic = configparser.ConfigParser()
        config_dic["EABhandler"] = {
            "eab_profiling": True,
            "eab_handler_file": "eab_handler_file",
        }
        eabl = Mock()
        eabl.EABhandler = "bar"
        mock_eabload.return_value = eabl
        self.assertEqual(
            (True, "bar"), self.config_eab_profile_load(self.logger, config_dic)
        )
        self.assertTrue(mock_eabload.called)

    @patch("acme2certifier.acme_srv.helpers.config.eab_handler_load")
    def test_342_config_eab_profile_load(self, mock_eabload):
        """test config_eab_profiling()"""
        config_dic = configparser.ConfigParser()
        config_dic["CAhandler"] = {"eab_profiling": True}
        config_dic["EABhandler"] = {"eab_handler_file": "eab_handler_file"}
        eabl = Mock()
        eabl.EABhandler = "bar"
        mock_eabload.return_value = eabl
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (True, "bar"), self.config_eab_profile_load(self.logger, config_dic)
            )
        self.assertTrue(mock_eabload.called)
        self.assertIn(
            "WARNING:test_a2c:eab_profiling found in CAhandler section - this is deprecated, please use EABhandler section",
            lcm.output,
        )

    @patch("acme2certifier.acme_srv.helpers.config.eab_handler_load")
    def test_343_config_eab_profile_load(self, mock_eabload):
        """test config_eab_profiling()"""
        config_dic = configparser.ConfigParser()
        config_dic["CAhandler"] = {"eab_profiling": "aa"}
        config_dic["EABhandler"] = {"eab_handler_file": "eab_handler_file"}
        eabl = Mock()
        eabl.EABhandler = "bar"
        mock_eabload.return_value = eabl
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (False, None), self.config_eab_profile_load(self.logger, config_dic)
            )
        self.assertFalse(mock_eabload.called)
        self.assertIn(
            "WARNING:test_a2c:eab_profiling found in CAhandler section - this is deprecated, please use EABhandler section",
            lcm.output,
        )
        self.assertIn(
            "ERROR:test_a2c:Failed to load eabprofile from configuration: Not a boolean: aa",
            lcm.output,
        )

    @patch("acme2certifier.acme_srv.helpers.config.eab_handler_load")
    def test_344_config_eab_profile_load(self, mock_eabload):
        """test config_eab_profiling()"""
        config_dic = configparser.ConfigParser()
        config_dic["EABhandler"] = {"eab_profiling": True}
        eabl = Mock()
        eabl.EABhandler = "bar"
        mock_eabload.return_value = eabl
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (True, None), self.config_eab_profile_load(self.logger, config_dic)
            )
        self.assertFalse(mock_eabload.called)
        self.assertIn(
            "CRITICAL:test_a2c:EABHandler configuration incomplete", lcm.output
        )
        self.assertFalse(mock_eabload.called)

    @patch("acme2certifier.acme_srv.helpers.config.eab_handler_load")
    def test_345_config_eab_profile_load(self, mock_eabload):
        """test config_eab_profiling()"""
        config_dic = configparser.ConfigParser()
        config_dic["EABhandler"] = {
            "eab_profiling": True,
            "eab_handler_file": "eab_handler_file",
        }
        mock_eabload.return_value = None
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (True, None), self.config_eab_profile_load(self.logger, config_dic)
            )
        self.assertTrue(mock_eabload.called)
        self.assertIn("CRITICAL:test_a2c:EABHandler could not get loaded", lcm.output)

    @patch("acme2certifier.acme_srv.helpers.config.eab_handler_load")
    def test_346_config_eab_profile_load(self, mock_eabload):
        """test config_eab_profiling()"""
        config_dic = configparser.ConfigParser()
        config_dic["EABhandler"] = {
            "eab_profiling": False,
            "eab_handler_file": "eab_handler_file",
        }
        self.assertEqual(
            (False, None), self.config_eab_profile_load(self.logger, config_dic)
        )
        self.assertFalse(mock_eabload.called)

    @patch("acme2certifier.acme_srv.helpers.config.eab_handler_load")
    def test_347_config_eab_profile_load(self, mock_eabload):
        """test config_eab_profiling()"""
        config_dic = configparser.ConfigParser()
        config_dic["EABhandler"] = {
            "eab_profiling": "aa",
            "eab_handler_file": "eab_handler_file",
        }
        self.assertEqual(
            (False, None), self.config_eab_profile_load(self.logger, config_dic)
        )
        self.assertFalse(mock_eabload.called)

    def test_348_eab_profile_string_check(self):
        """test _eab_profile_string_check()"""
        cahandler = FakeDBStore()
        cahandler.foo = "foo"
        self.eab_profile_string_check(self.logger, cahandler, "foo", "bar")
        self.assertEqual("bar", cahandler.foo)

    def test_349_eab_profile_string_check(self):
        """test _eab_profile_string_check()"""
        cahandler = FakeDBStore()
        cahandler.foo = "foo"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.eab_profile_string_check(self.logger, cahandler, "foobar", "bar")
        self.assertEqual("foo", cahandler.foo)
        self.assertIn(
            "WARNING:test_a2c:EAB profile string checking: ignoring unrecognized string attribute: key: foobar value: bar",
            lcm.output,
        )

    def test_350_eab_profile_list_check(self):
        """test _eab_profile_list_check()"""
        cahandler = FakeDBStore()
        cahandler.foo = "foo"
        eabhandler = Mock()
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.eab_profile_list_check(
                self.logger, cahandler, eabhandler, "csr", "foobar", "bar"
            )
        self.assertEqual("foo", cahandler.foo)
        self.assertIn(
            "WARNING:test_a2c:EAP profile list checking: ignoring unrecognized list attribute: key: foobar value: bar",
            lcm.output,
        )

    @patch("acme2certifier.acme_srv.helpers.eab.allowed_domainlist_check")
    def test_351_eab_profile_list_check(self, mock_chk):
        """test _eab_profile_list_check()"""
        cahandler = FakeDBStore()
        eabhandler = Mock()
        mock_chk.return_value = False
        cahandler.foo = "foo"
        self.eab_profile_list_check(
            self.logger, cahandler, eabhandler, "csr", "allowed_domainlist", "bar"
        )
        self.assertEqual("foo", cahandler.foo)

    @patch("acme2certifier.acme_srv.helpers.eab.allowed_domainlist_check")
    def test_352_eab_profile_list_check(self, mock_chk):
        """test _eab_profile_list_check()"""
        cahandler = FakeDBStore()
        mock_chk.return_value = "error"
        cahandler.foo = "foo"
        eabhandler = Mock()
        self.assertEqual(
            "error",
            self.eab_profile_list_check(
                self.logger, cahandler, eabhandler, "csr", "allowed_domainlist", "bar"
            ),
        )
        self.assertEqual("foo", cahandler.foo)

    @patch("acme2certifier.acme_srv.helpers.eab.allowed_domainlist_check")
    @patch("acme2certifier.acme_srv.helpers.eab.client_parameter_validate")
    def test_353_eab_profile_list_check(self, mock_hifv, mock_chk):
        """test _eab_profile_list_check()"""
        cahandler = FakeDBStore()
        cahandler.foo = "foo"
        cahandler.header_info_field = "header_info_field"
        mock_chk.return_value = "error"
        cahandler.foo = "foo"
        eabhandler = Mock()
        mock_hifv.return_value = ("mock_hifv", None)
        self.assertFalse(
            self.eab_profile_list_check(
                self.logger, cahandler, eabhandler, "csr", "foo", "bar"
            )
        )
        self.assertEqual("mock_hifv", cahandler.foo)

    @patch("acme2certifier.acme_srv.helpers.eab.allowed_domainlist_check")
    @patch("acme2certifier.acme_srv.helpers.eab.client_parameter_validate")
    def test_354_eab_profile_list_check(self, mock_hifv, mock_chk):
        """test _eab_profile_list_check()"""
        cahandler = FakeDBStore()
        cahandler.foo = "foo"
        cahandler.header_info_field = "header_info_field"
        mock_chk.return_value = "error"
        cahandler.foo = "foo"
        eabhandler = Mock()
        mock_hifv.return_value = (None, "error")
        self.assertEqual(
            "error",
            self.eab_profile_list_check(
                self.logger, cahandler, eabhandler, "csr", "foo", "bar"
            ),
        )
        self.assertEqual("foo", cahandler.foo)

    @patch("acme2certifier.acme_srv.helpers.eab.allowed_domainlist_check")
    def test_355_eab_profile_list_check(self, mock_chk):
        """test _eab_profile_list_check() test allowed domain check if cahander contains attribute"""
        cahandler = FakeDBStore()
        mock_chk.return_value = False
        cahandler.allowed_domainlist = ["foo", "foobar"]
        cahandler.foo = "foo"
        cahandler.header_info_field = None
        eabhandler = Mock()
        self.assertFalse(
            self.eab_profile_list_check(
                self.logger, cahandler, eabhandler, "csr", "allowed_domainlist", ["bar"]
            )
        )
        self.assertEqual("foo", cahandler.foo)
        self.assertEqual(["foo", "foobar"], cahandler.allowed_domainlist)
        self.assertTrue(mock_chk.called)

    @patch("acme2certifier.acme_srv.helpers.eab.allowed_domainlist_check")
    def test_356_eab_profile_list_check(self, mock_chk):
        """test _eab_profile_list_check() test allowed domain check if eabhandler contains attribute"""
        cahandler = FakeDBStore()
        mock_chk.return_value = False
        cahandler.allowed_domainlist = ["foo", "foobar"]
        cahandler.foo = "foo"
        cahandler.header_info_field = None
        eabhandler = Mock()
        eabhandler.allowed_domains_check.return_value = False
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(
                self.eab_profile_list_check(
                    self.logger,
                    cahandler,
                    eabhandler,
                    "csr",
                    "allowed_domainlist",
                    ["bar"],
                )
            )
        self.assertIn(
            "INFO:test_a2c:Execute allowed_domains_check() from eab handler", lcm.output
        )
        self.assertEqual("foo", cahandler.foo)
        self.assertEqual(["foo", "foobar"], cahandler.allowed_domainlist)
        self.assertFalse(mock_chk.called)

    @patch("acme2certifier.acme_srv.helpers.eab.allowed_domainlist_check")
    def test_357_eab_profile_list_check(self, mock_chk):
        """test _eab_profile_list_check() test allowed domain check if eabhandler contains attribute"""
        cahandler = FakeDBStore()
        mock_chk.return_value = False
        cahandler.allowed_domainlist = ["foo", "foobar"]
        cahandler.foo = "foo"
        cahandler.header_info_field = None
        eabhandler = Mock()
        eabhandler.allowed_domains_check.return_value = "eab_error"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                "eab_error",
                self.eab_profile_list_check(
                    self.logger,
                    cahandler,
                    eabhandler,
                    "csr",
                    "allowed_domainlist",
                    ["bar"],
                ),
            )
        self.assertIn(
            "INFO:test_a2c:Execute allowed_domains_check() from eab handler", lcm.output
        )
        self.assertEqual("foo", cahandler.foo)
        self.assertEqual(["foo", "foobar"], cahandler.allowed_domainlist)
        self.assertFalse(mock_chk.called)

    @patch("acme2certifier.acme_srv.helpers.eab.profile_lookup")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_check")
    @patch("acme2certifier.acme_srv.helpers.eab.header_info_lookup")
    def test_358_eab_profile_header_info_check(
        self, mock_lookup, mock_eab, mock_profile
    ):
        """test eab_profile_header_info_check()"""
        cahandler = FakeDBStore()
        cahandler.eab_profiling = False
        cahandler.header_info_field = None
        self.assertFalse(
            self.eab_profile_header_info_check(
                self.logger, cahandler, "csr", "handler_hifield"
            )
        )
        self.assertFalse(mock_lookup.called)
        self.assertFalse(mock_eab.called)
        self.assertFalse(mock_profile.called)

    @patch("acme2certifier.acme_srv.helpers.eab.profile_lookup")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_check")
    @patch("acme2certifier.acme_srv.helpers.eab.header_info_lookup")
    def test_359_eab_profile_header_info_check(
        self, mock_lookup, mock_eab, mock_profile
    ):
        """test eab_profile_header_info_check()"""
        cahandler = FakeDBStore()
        cahandler.eab_profiling = False
        cahandler.header_info_field = None
        cahandler.profiles = {"profile": "profile"}
        mock_profile.return_value = "profile_value"
        self.assertFalse(
            self.eab_profile_header_info_check(
                self.logger, cahandler, "csr", "handler_hifield"
            )
        )
        self.assertFalse(mock_lookup.called)
        self.assertFalse(mock_eab.called)
        self.assertTrue(mock_profile.called)
        self.assertEqual("profile_value", cahandler.handler_hifield)

    @patch("acme2certifier.acme_srv.helpers.eab.profile_lookup")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_check")
    @patch("acme2certifier.acme_srv.helpers.eab.header_info_lookup")
    def test_360_eab_profile_header_info_check(
        self, mock_lookup, mock_eab, mock_profile
    ):
        """test eab_profile_header_info_check()"""
        cahandler = FakeDBStore()
        cahandler.eab_profiling = False
        cahandler.header_info_field = None
        cahandler.handler_hifield = "old_value"
        cahandler.profiles = {"profile": "profile"}
        mock_profile.return_value = None
        self.assertFalse(
            self.eab_profile_header_info_check(
                self.logger, cahandler, "csr", "handler_hifield"
            )
        )
        self.assertFalse(mock_lookup.called)
        self.assertFalse(mock_eab.called)
        self.assertTrue(mock_profile.called)
        self.assertEqual("old_value", cahandler.handler_hifield)

    @patch("acme2certifier.acme_srv.helpers.eab.profile_lookup")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_check")
    @patch("acme2certifier.acme_srv.helpers.eab.header_info_lookup")
    def test_361_eab_profile_header_info_check(
        self, mock_lookup, mock_eab, mock_profile
    ):
        """test eab_profile_header_info_check()"""
        cahandler = FakeDBStore()
        cahandler.eab_profiling = False
        cahandler.header_info_field = "hi_field"
        mock_lookup.return_value = "hi_value"
        cahandler.hi_field = "pre_hi_field"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(
                self.eab_profile_header_info_check(
                    self.logger, cahandler, "csr", "hi_field"
                )
            )
        self.assertIn(
            "INFO:test_a2c:Received enrollment parameter: hi_field value: hi_value via headerinfo field",
            lcm.output,
        )
        self.assertEqual("hi_value", cahandler.hi_field)
        self.assertTrue(mock_lookup.called)
        self.assertFalse(mock_eab.called)
        self.assertFalse(mock_profile.called)

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_check")
    @patch("acme2certifier.acme_srv.helpers.eab.header_info_lookup")
    def test_362_eab_profile_header_info_check(self, mock_lookup, mock_eab):
        """test eab_profile_header_info_check()"""
        cahandler = FakeDBStore()
        cahandler.eab_profiling = False
        cahandler.header_info_field = "hi_field"
        mock_lookup.return_value = "hi_value"
        cahandler.hi_field = "pre_hi_field"
        cahandler.profile_name = "profile_name"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(
                self.eab_profile_header_info_check(self.logger, cahandler, "csr")
            )
        self.assertIn(
            "INFO:test_a2c:Received enrollment parameter: profile_name value: hi_value via headerinfo field",
            lcm.output,
        )
        self.assertEqual("pre_hi_field", cahandler.hi_field)
        self.assertEqual("hi_value", cahandler.profile_name)
        self.assertTrue(mock_lookup.called)
        self.assertFalse(mock_eab.called)

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_check")
    @patch("acme2certifier.acme_srv.helpers.eab.header_info_lookup")
    def test_363_eab_profile_header_info_check(self, mock_lookup, mock_eab):
        """test eab_profile_header_info_check()"""
        cahandler = FakeDBStore()
        cahandler.eab_profiling = False
        cahandler.header_info_field = "hi_field"
        mock_lookup.return_value = None
        cahandler.hi_field = "pre_hi_field"
        cahandler.profile_name = "profile_name"
        self.assertFalse(
            self.eab_profile_header_info_check(self.logger, cahandler, "csr")
        )
        self.assertEqual("pre_hi_field", cahandler.hi_field)
        self.assertEqual("profile_name", cahandler.profile_name)
        self.assertFalse(mock_eab.called)

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_check")
    @patch("acme2certifier.acme_srv.helpers.eab.header_info_lookup")
    def test_364_eab_profile_header_info_check(self, mock_lookup, mock_eab):
        """test eab_profile_header_info_check()"""
        cahandler = FakeDBStore()
        cahandler.eab_profiling = True
        cahandler.eab_handler = None
        cahandler.header_info_field = "hi_field"
        mock_lookup.return_value = "hi_value"
        cahandler.hi_field = "pre_hi_field"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                "Eab_profiling enabled but no handler defined",
                self.eab_profile_header_info_check(
                    self.logger, cahandler, "csr", "hi_field"
                ),
            )
        self.assertIn(
            "ERROR:test_a2c:EAB profiling enabled but no handler defined",
            lcm.output,
        )
        self.assertEqual("pre_hi_field", cahandler.hi_field)
        self.assertFalse(mock_eab.called)
        self.assertFalse(mock_lookup.called)

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_check")
    @patch("acme2certifier.acme_srv.helpers.eab.header_info_lookup")
    def test_365_eab_profile_header_info_check(self, mock_lookup, mock_eab):
        """test eab_profile_header_info_check()"""
        cahandler = FakeDBStore()
        cahandler.eab_profiling = True
        cahandler.eab_handler = "eab_handler"
        cahandler.header_info_field = "hi_field"
        mock_lookup.return_value = "hi_value"
        mock_eab.return_value = "mock_eab"
        cahandler.hi_field = "pre_hi_field"
        self.assertEqual(
            "mock_eab",
            self.eab_profile_header_info_check(
                self.logger, cahandler, "csr", "hi_field"
            ),
        )
        self.assertEqual("pre_hi_field", cahandler.hi_field)
        self.assertFalse(mock_lookup.called)
        self.assertTrue(mock_eab.called)

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_list_check")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_string_check")
    def test_366_eab_profile_check(self, mock_string, mock_list):
        """test _eab_profile_check()"""
        self.cahandler = MagicMock()
        self.csr = "testCSR"
        self.handler_hifield = "testField"
        self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {
            "testField": "stringValue"
        }
        self.assertIsNone(
            self.eab_profile_check(
                self.logger, self.cahandler, self.csr, self.handler_hifield
            )
        )
        self.assertTrue(mock_string.called)
        self.assertFalse(mock_list.called)

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_list_check")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_string_check")
    def test_367_eab_profile_check(self, mock_string, mock_list):
        self.cahandler = MagicMock()
        self.csr = "testCSR"
        self.handler_hifield = "testField"
        self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {
            "testField": ["listValue"]
        }
        mock_list.return_value = None
        self.assertIsNone(
            self.eab_profile_check(
                self.logger, self.cahandler, self.csr, self.handler_hifield
            )
        )
        self.assertFalse(mock_string.called)
        self.assertTrue(mock_list.called)

    @patch("acme2certifier.acme_srv.helpers.eab.header_info_lookup")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_list_check")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_string_check")
    def test_368_eab_profile_check(self, mock_string, mock_list, mock_hil):
        self.cahandler = MagicMock()
        self.csr = "testCSR"
        self.handler_hifield = "testField"
        self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {
            "testField": ["listValue"]
        }
        mock_list.return_value = "mock_list"
        self.assertEqual(
            "mock_list",
            self.eab_profile_check(
                self.logger, self.cahandler, self.csr, self.handler_hifield
            ),
        )
        self.assertFalse(mock_string.called)
        self.assertTrue(mock_list.called)
        self.assertFalse(mock_hil.called)

    @patch("acme2certifier.acme_srv.helpers.eab.header_info_lookup")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_list_check")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_string_check")
    def test_369_eab_profile_check(self, mock_string, mock_list, mock_hil):
        self.cahandler = MagicMock()
        self.csr = "testCSR"
        self.handler_hifield = "testField"
        self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {
            "testField1": ["listValue"]
        }
        mock_list.return_value = "mock_list"
        self.assertEqual(
            'header_info field "testField" is not allowed by profile',
            self.eab_profile_check(
                self.logger, self.cahandler, self.csr, self.handler_hifield
            ),
        )
        self.assertFalse(mock_string.called)
        self.assertTrue(mock_list.called)
        self.assertTrue(mock_hil.called)

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_list_check")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_string_check")
    def test_370_eab_profile_check(self, mock_string, mock_list):
        self.cahandler = MagicMock()
        self.csr = "testCSR"
        self.handler_hifield = "testField"
        self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {
            "testField": ["listValue"]
        }
        self.cahandler.eab_profile_list_check.return_value = "eab_list_check"
        mock_list.return_value = None
        self.assertEqual(
            "eab_list_check",
            self.eab_profile_check(
                self.logger, self.cahandler, self.csr, self.handler_hifield
            ),
        )
        self.assertFalse(mock_string.called)
        self.assertFalse(mock_list.called)

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_subject_check")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_list_check")
    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_string_check")
    def test_371_eab_profile_check(self, mock_string, mock_list, mock_subject):
        self.cahandler = MagicMock()
        self.csr = "testCSR"
        self.handler_hifield = None
        mock_subject.return_value = "mock_subject"
        self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {
            "subject": ["listValue"]
        }
        self.cahandler.eab_profile_list_check.return_value = "eab_list_check"
        mock_list.return_value = None
        self.assertEqual(
            "mock_subject",
            self.eab_profile_check(
                self.logger, self.cahandler, self.csr, self.handler_hifield
            ),
        )
        self.assertFalse(mock_string.called)
        self.assertFalse(mock_list.called)
        self.assertTrue(mock_subject.called)

    @patch("cryptography.__version__", "3.4.7")
    def test_372_cryptography_version_get_success(self):
        self.assertEqual(3, self.cryptography_version_get(self.logger))

    @patch("cryptography.__version__", None)
    def test_373_cryptography_version_get_success(self):
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(36, self.cryptography_version_get(self.logger))
        self.assertIn(
            "ERROR:test_a2c:Error while getting the version number of the cryptography module: 'NoneType' object has no attribute 'split'",
            lcm.output,
        )

    @patch("acme2certifier.acme_srv.helpers.validation.validate_fqdn")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_ip")
    def test_374_cn_validate(self, mock_ip, mock_fqdn):
        """test cn_validate()"""
        mock_ip.return_value = True
        mock_fqdn.return_value = True
        self.assertFalse(self.cn_validate(self.logger, "foo.bar.com"))
        self.assertFalse(mock_fqdn.called)

    @patch("acme2certifier.acme_srv.helpers.validation.validate_fqdn")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_ip")
    def test_375_cn_validate(self, mock_ip, mock_fqdn):
        """test cn_validate()"""
        mock_ip.return_value = False
        mock_fqdn.return_value = True
        self.assertFalse(self.cn_validate(self.logger, "foo.bar.com"))
        self.assertTrue(mock_fqdn.called)

    @patch("acme2certifier.acme_srv.helpers.validation.validate_fqdn")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_ip")
    def test_376_cn_validate(self, mock_ip, mock_fqdn):
        """test cn_validate()"""
        mock_ip.return_value = False
        mock_fqdn.return_value = False
        self.assertEqual(
            "Profile subject check failed: CN validation failed",
            self.cn_validate(self.logger, "foo.bar.com"),
        )
        self.assertTrue(mock_fqdn.called)

    @patch("acme2certifier.acme_srv.helpers.validation.validate_fqdn")
    @patch("acme2certifier.acme_srv.helpers.validation.validate_ip")
    def test_377_cn_validate(self, mock_ip, mock_fqdn):
        """test cn_validate()"""
        mock_ip.return_value = False
        mock_fqdn.return_value = False
        self.assertEqual(
            "Profile subject check failed: commonName missing",
            self.cn_validate(self.logger, None),
        )
        self.assertFalse(mock_fqdn.called)

    def test_378_csr_subject_get(self):
        """test csr_subject_get()"""
        csr = "MIICwDCCAagCAQAwVDESMBAGA1UEAwwJbGVnby5hY21lMQ0wCwYDVQQKDARhY21lMQwwCgYDVQQLDANmb28xCzAJBgNVBAYTAlVTMRQwEgYDVQQFEwswMC0xMS0yMi0zMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM5AKMmB3o8LLEEGuHo0Ipl4K8z9m3EyM9teSVocQz39DK8s2dKpx8MrsVkTg6M3fuL4yPlim8v0+unPtB18dFeThkijHetxL5x08pVvMVwa7Cjk/22e5IRgBGSQYCO6KCUsNh2vhH93r7x71wlTV3sYe2t0HaEdGqBxdct76J9kyeCY06Br+4PMR7afRvHv4vFH6Y2+hSD4oOd5cSTZXnNWcWRbjNFY7aytzl4JpJiEK0ealDMSf/ZP0n8Sdx1vCx8amaozrLg5z3eLULiAUUgCtqOWOgNLQFNSqjyhZmMTZGGJcTgb43KAKWsO3bfM6rvNTZRbrM7dAsg/bQsK6mMCAwEAAaAnMCUGCSqGSIb3DQEJDjEYMBYwFAYDVR0RBA0wC4IJbGVnby5hY21lMA0GCSqGSIb3DQEBCwUAA4IBAQA19j8Lge9Vqxc/hvWYcU1Kx3KBx5TN97PK0wQFPIIWX20/JRoodzfrMSqO0EgZWB+czoRi8G+2ezbK13sV02dKovo8ISoSvgSZtt53UKBz+JmQd7Q7G1vONZ7d2PT0nTUN4fTA5YQs5nys3O8/2oOxJiJO6IyhmpiVqUbrlU6Harb4MfjNTb+teSQRSCOAX/8U9TdPwuAi6rXdWjXAUxBDQySWkW/B3pd77Ztt5nDFP2DT+7f7mAoWG4+XY6iXcXs1GsDA4XRTx2rCvhQtQomVGAKFwd8aTpHL/ZwNt1GOw6oMZkKKf+axVA1pvAYGhey/4x3uwKf654VB3e2iOCea"
        result_dic = {
            "commonName": "lego.acme",
            "organizationName": "acme",
            "organizationalUnitName": "foo",
            "countryName": "US",
            "serialNumber": "00-11-22-33",
        }
        self.assertEqual(result_dic, self.csr_subject_get(self.logger, csr))

    def test_379_csr_subject_get(self):
        """test csr_subject_get()"""
        csr = "MIICtjCCAZ4CAQAwQjELMAkGA1UEBhMCREUxDjAMBgNVBAoMBXRlc3RPMQ8wDQYDVQQLDAZ0ZXN0T1UxEjAQBgNVBGEMCTEyMzQ1NjctODCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALs0a3qYQOIkpuRa34QEb+j9PzkMC8eA8bT9icRnpd1DO5LyQjc0OreV8ed3YeV1IVtcf1qX4AYKdIb1X1qa1pFkcneFZsX6B1i/ofRqEXrsN243V4LTjHFwIqwIecFX/Ml9rhCV+/tRTBrl3XIyI2xhZ4qtxIWkavmrvhNy4gY0YBjw4D67NzDJ9gm9Nx8VFzGZxXP0MgOtLOJ7BMCcqJmBwdItaotFCCkQfXC6S+n9sLP3GYrgyShaXMAebYmkNPZ4YJ0H28VfBGcWF2hpmSBgZ15Bj5P3PNYAnAocCUkwcifk3CZoJwcmC1Fm2mC8zOAEQ+GA/KqM6RHmMMKHexECAwEAAaAvMC0GCSqGSIb3DQEJDjEgMB4wHAYDVR0RBBUwE4IRYWNtZS1jbGllbnQubG9jYWwwDQYJKoZIhvcNAQELBQADggEBAB6HE9CMFKvyM4kwmKKeAoXzLhILTWmjDgI1+wBEq781CqXS3/rhTRYxFCjaU4WUFSHFUOo4+qlehwQzFRBLwEdgIylKXVT7etuto9lHU7xpf+wRth3c/PF/DsibC3S+fzlA7UBgxvhO0FbuqnV4pUUp/Y/jsaB4+IWhnwySh+378A98VkLU/1muSaM5AS9rboYyFPtevWzeSZJtz7CLAK2zWJ95ApOIBXHQdm6wsgJzwTTW1apXofNTX5AM6L0TPdieiPKUHPpH2AJZjzCVX9NuhDhLL5klzYwIrvcD2bxGy+xNWAYxXyLhPkGG8F954FAFa66sqiQBlmU92ndtG3Q="
        result_dic = {
            "organizationIdentifier": "1234567-8",
            "organizationName": "testO",
            "organizationalUnitName": "testOU",
            "countryName": "DE",
        }
        self.assertEqual(result_dic, self.csr_subject_get(self.logger, csr))

    def test_380_csr_subject_get(self):
        """test csr_subject_get()"""
        csr = "MIICcDCCAVgCAQAwADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOKk0E61QJ2K/NiGSO0aJyqrLfmHytPr35ptLwNdfKQ/8Vb2uoHYAvxVEO9weNTQVlZ9ApkJquBTRoSdqTy6p87inh8JwzFM/neJAsMg2ZiH3gRRRfmIb/4Kce0BUQ66DFSV8sWThyv13EcL+pZYdqRvONujVn7XVPbmB2ZI8qI4iXswRq45mFBW5Dyt3Rlw+KOBu1ejo0lqB2FGQiBONxQrFDyF4nVWN3R9BlhuybSF4Elhos7pkiEfrE+8EzYy+7yMEiDh1m+TmwZRNEdtSWNORF51CF3bYUz8pvpt66vKGi/F6k2iljelw1kNsswZAciNi2jG7S0M+MWMFi680sCAwEAAaArMCkGCSqGSIb3DQEJDjEcMBowGAYDVR0RBBEwD4INZm9vLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAivCrcL+uVzDdykT87073atC4B2DHky5bzL+iI8C+BkPq0jRdcVkExMrUtTdtp8Ot1zQHtYc/c/Tj+aYDZ6SdMYtrtHUgxS5JyFh0p+MEvkgZHcWOVC+VlWA+lC9kdX3WetsGT6xqCG4l+BpgCUERghFJ5/+K0bbCI4jT/5ZCT7+pO0qZtw0eg6tQBLPSXzXN98x3nmuaw9PzO1rVG5IMItyU+TlX3pJRXKpqSOHEbeaGWHizMUlbDKzoIiUf+11I9RwTeLlp/HPG8uvRc/zZ1einZPLQgow5kU15jFQSgQtzFHV4ZxuYmWN7oMIruwBNP1hkoTNL1kJcPeOwtEdOMw=="
        self.assertFalse(self.csr_subject_get(self.logger, csr))

    @patch("acme2certifier.acme_srv.helpers.eab.cn_validate")
    def test_381_eab_profile_subjet_string_check(self, mock_validate):
        """test eab_profile_subject_string_check()"""
        profile_dic = {"foo": "bar1"}
        self.assertEqual(
            "Profile subject check failed for foo",
            self.eab_profile_subject_string_check(
                self.logger, profile_dic, "foo", "bar"
            ),
        )
        self.assertFalse(mock_validate.called)

    @patch("acme2certifier.acme_srv.helpers.eab.cn_validate")
    def test_382_eab_profile_subjet_string_check(self, mock_validate):
        """test eab_profile_subject_string_check()"""
        profile_dic = {"foo": "*"}
        self.assertFalse(
            self.eab_profile_subject_string_check(
                self.logger, profile_dic, "foo", "bar"
            )
        )
        self.assertFalse(mock_validate.called)

    @patch("acme2certifier.acme_srv.helpers.eab.cn_validate")
    def test_383_eab_profile_subjet_string_check(self, mock_validate):
        """test eab_profile_subject_string_check()"""
        profile_dic = {"foo": "bar"}
        self.assertFalse(
            self.eab_profile_subject_string_check(
                self.logger, profile_dic, "foo", "bar"
            )
        )
        self.assertFalse(mock_validate.called)

    @patch("acme2certifier.acme_srv.helpers.eab.cn_validate")
    def test_384_eab_profile_subjet_string_check(self, mock_validate):
        """test eab_profile_subject_string_check()"""
        profile_dic = {"foo": ["bar1", "bar2", "bar3"]}
        self.assertEqual(
            "Profile subject check failed for foo",
            self.eab_profile_subject_string_check(
                self.logger, profile_dic, "foo", "bar"
            ),
        )
        self.assertFalse(mock_validate.called)

    @patch("acme2certifier.acme_srv.helpers.eab.cn_validate")
    def test_385_eab_profile_subjet_string_check(self, mock_validate):
        """test eab_profile_subject_string_check()"""
        profile_dic = {"foo": ["bar1", "bar2", "bar3"]}
        self.assertFalse(
            self.eab_profile_subject_string_check(
                self.logger, profile_dic, "foo", "bar2"
            )
        )
        self.assertFalse(mock_validate.called)

    @patch("acme2certifier.acme_srv.helpers.eab.cn_validate")
    def test_386_eab_profile_subjet_string_check(self, mock_validate):
        """test eab_profile_subject_string_check()"""
        profile_dic = {"foo": ["bar1", "bar2", "bar3"]}
        mock_validate.return_value = "error"
        self.assertEqual(
            "error",
            self.eab_profile_subject_string_check(
                self.logger, profile_dic, "commonName", "bar"
            ),
        )
        self.assertTrue(mock_validate.called)

    @patch("acme2certifier.acme_srv.helpers.eab.cn_validate")
    def test_387_eab_profile_subjet_string_check(self, mock_validate):
        """test eab_profile_subject_string_check()"""
        profile_dic = {"foo": ["bar1", "bar2", "bar3"]}
        mock_validate.return_value = "error"
        self.assertEqual(
            "Profile subject check failed for bar",
            self.eab_profile_subject_string_check(
                self.logger, profile_dic, "bar", "bar"
            ),
        )
        self.assertFalse(mock_validate.called)

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_subject_string_check")
    @patch("acme2certifier.acme_srv.helpers.eab.csr_subject_get")
    def test_388_eab_profile_subject_check(self, mock_cn, mock_strchk):
        """test eab_profile_subject_check()"""
        profile_dic = {"foo": "bar"}
        mock_cn.return_value = {"o": "o", "ou": "ou", "cn": "cn"}
        mock_strchk.side_effect = ["o", "ou", "cn"]
        self.assertEqual(
            "o", self.eab_profile_subject_check(self.logger, "csr", profile_dic)
        )

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_subject_string_check")
    @patch("acme2certifier.acme_srv.helpers.eab.csr_subject_get")
    def test_389_eab_profile_subject_check(self, mock_cn, mock_strchk):
        """test eab_profile_subject_check()"""
        profile_dic = {"foo": "bar"}
        mock_cn.return_value = {"o": "o", "ou": "ou", "cn": "cn"}
        mock_strchk.side_effect = [False, "ou", "cn"]
        self.assertEqual(
            "ou", self.eab_profile_subject_check(self.logger, "csr", profile_dic)
        )

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_subject_string_check")
    @patch("acme2certifier.acme_srv.helpers.eab.csr_subject_get")
    def test_390_eab_profile_subject_check(self, mock_cn, mock_strchk):
        """test eab_profile_subject_check()"""
        profile_dic = {"foo": "bar"}
        mock_cn.return_value = {"o": "o", "ou": "ou", "cn": "cn"}
        mock_strchk.side_effect = [False, False, "cn"]
        self.assertEqual(
            "cn", self.eab_profile_subject_check(self.logger, "csr", profile_dic)
        )

    @patch("acme2certifier.acme_srv.helpers.eab.eab_profile_subject_string_check")
    @patch("acme2certifier.acme_srv.helpers.eab.csr_subject_get")
    def test_391_eab_profile_subject_check(self, mock_cn, mock_strchk):
        """test eab_profile_subject_check()"""
        profile_dic = {"foo": "bar"}
        mock_cn.return_value = {"o": "o", "ou": "ou", "cn": "cn"}
        mock_strchk.side_effect = [False, False, False]
        self.assertEqual(
            "Profile subject check failed",
            self.eab_profile_subject_check(self.logger, "csr", profile_dic),
        )

    @patch("acme2certifier.acme_srv.helpers.csr.csr_san_get")
    @patch("acme2certifier.acme_srv.helpers.csr.csr_cn_get")
    def test_392_csr_cn_lookup(self, mock_cnget, mock_san_get):
        """test _csr_cn_lookup()"""
        mock_cnget.return_value = "cn"
        mock_san_get.return_value = ["foo:san1", "foo:san2"]
        self.assertEqual("cn", self.csr_cn_lookup(self.logger, "csr"))

    @patch("acme2certifier.acme_srv.helpers.csr.csr_san_get")
    @patch("acme2certifier.acme_srv.helpers.csr.csr_cn_get")
    def test_393_csr_cn_lookup(self, mock_cnget, mock_san_get):
        """test _csr_cn_lookup()"""
        mock_cnget.return_value = None
        mock_san_get.return_value = ["foo:san1", "foo:san2"]
        self.assertEqual("san1", self.csr_cn_lookup(self.logger, "csr"))

    @patch("acme2certifier.acme_srv.helpers.csr.csr_san_get")
    @patch("acme2certifier.acme_srv.helpers.csr.csr_cn_get")
    def test_394_csr_cn_lookup(self, mock_cnget, mock_san_get):
        """test _csr_cn_lookup()"""
        mock_cnget.return_value = None
        mock_san_get.return_value = ["foosan1", "foo:san2"]
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual("san2", self.csr_cn_lookup(self.logger, "csr"))
        self.assertIn(
            "ERROR:test_a2c:SAN split failed: list index out of range", lcm.output
        )

    @patch("acme2certifier.acme_srv.helpers.csr.csr_san_get")
    @patch("acme2certifier.acme_srv.helpers.csr.csr_cn_get")
    def test_395_csr_cn_lookup(self, mock_cnget, mock_san_get):
        """test _csr_cn_lookup()"""
        mock_cnget.return_value = None
        mock_san_get.return_value = None
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.csr_cn_lookup(self.logger, "csr"))
        self.assertIn("ERROR:test_a2c:No SANs found in CSR", lcm.output)

    @patch("acme2certifier.acme_srv.helpers.network.requests.put")
    @patch("acme2certifier.acme_srv.helpers.network.requests.post")
    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_396_request_operation(self, mock_get, mock_post, mock_put):
        """test request_operation()"""
        mockresponse_get = Mock()
        mockresponse_get.status_code = "status_code"
        mockresponse_get.json = lambda: {"get": "get"}
        mock_get.return_value = mockresponse_get
        mockresponse_post = Mock()
        mockresponse_post.status_code = "status_code"
        mockresponse_post.json = lambda: {"post": "post"}
        mock_post.return_value = mockresponse_post
        mockresponse_put = Mock()
        mockresponse_put.status_code = "status_code"
        mockresponse_put.json = lambda: {"put": "put"}
        mock_put.return_value = mockresponse_put
        self.assertEqual(
            ("status_code", {"get": "get"}),
            self.request_operation(logger=self.logger, url="foo", method="get"),
        )
        self.assertTrue(mock_get.called)
        self.assertFalse(mock_post.called)
        self.assertFalse(mock_put.called)

    @patch("acme2certifier.acme_srv.helpers.network.requests.put")
    @patch("acme2certifier.acme_srv.helpers.network.requests.post")
    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_397_request_operation(self, mock_get, mock_post, mock_put):
        """test request_operation()"""
        mockresponse_get = Mock()
        mockresponse_get.status_code = "status_code"
        mockresponse_get.json = lambda: {"get": "get"}
        mock_get.return_value = mockresponse_get
        mockresponse_post = Mock()
        mockresponse_post.status_code = "status_code"
        mockresponse_post.json = lambda: {"post": "post"}
        mock_post.return_value = mockresponse_post
        mockresponse_put = Mock()
        mockresponse_put.status_code = "status_code"
        mockresponse_put.json = lambda: {"put": "put"}
        mock_put.return_value = mockresponse_put
        self.assertEqual(
            ("status_code", {"post": "post"}),
            self.request_operation(logger=self.logger, url="foo", method="post"),
        )
        self.assertFalse(mock_get.called)
        self.assertTrue(mock_post.called)
        self.assertFalse(mock_put.called)

    @patch("acme2certifier.acme_srv.helpers.network.requests.put")
    @patch("acme2certifier.acme_srv.helpers.network.requests.post")
    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_398_request_operation(self, mock_get, mock_post, mock_put):
        """test request_operation()"""
        mockresponse_get = Mock()
        mockresponse_get.status_code = "status_code"
        mockresponse_get.json = lambda: {"get": "get"}
        mock_get.return_value = mockresponse_get
        mockresponse_post = Mock()
        mockresponse_post.status_code = "status_code"
        mockresponse_post.json = lambda: {"post": "post"}
        mock_post.return_value = mockresponse_post
        mockresponse_put = Mock()
        mockresponse_put.status_code = "status_code"
        mockresponse_put.json = lambda: {"put": "put"}
        mock_put.return_value = mockresponse_put
        self.assertEqual(
            ("status_code", {"put": "put"}),
            self.request_operation(logger=self.logger, url="foo", method="put"),
        )
        self.assertFalse(mock_get.called)
        self.assertFalse(mock_post.called)
        self.assertTrue(mock_put.called)

    @patch("acme2certifier.acme_srv.helpers.network.requests.put")
    @patch("acme2certifier.acme_srv.helpers.network.requests.post")
    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_399_request_operation(self, mock_get, mock_post, mock_put):
        """test request_operation()"""
        mockresponse_get = Mock()
        mockresponse_get.status_code = "status_code"
        mockresponse_get.json = "string"
        mock_get.return_value = mockresponse_get
        self.assertEqual(
            ("status_code", "'str' object is not callable"),
            self.request_operation(logger=self.logger, url="foo", method="get"),
        )
        self.assertTrue(mock_get.called)
        self.assertFalse(mock_post.called)
        self.assertFalse(mock_put.called)

    @patch("acme2certifier.acme_srv.helpers.network.requests.put")
    @patch("acme2certifier.acme_srv.helpers.network.requests.post")
    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_400_request_operation(self, mock_get, mock_post, mock_put):
        """test request_operation()"""
        mockresponse_get = Mock()
        mockresponse_get.status_code = "status_code"
        mockresponse_get.json = "string"
        mockresponse_get.text = None
        mock_get.return_value = mockresponse_get
        self.assertEqual(
            ("status_code", None),
            self.request_operation(logger=self.logger, url="foo", method="get"),
        )
        self.assertTrue(mock_get.called)
        self.assertFalse(mock_post.called)
        self.assertFalse(mock_put.called)

    @patch("acme2certifier.acme_srv.helpers.network.requests.put")
    @patch("acme2certifier.acme_srv.helpers.network.requests.post")
    @patch("acme2certifier.acme_srv.helpers.network.requests.get")
    def test_401_request_operation(self, mock_get, mock_post, mock_put):
        """test request_operation()"""
        mockresponse_get = Mock()
        mockresponse_get.status_code = "status_code"
        mockresponse_get.json = "string"
        mockresponse_get.text = None
        mock_get.return_value = mockresponse_get
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (500, "'NoneType' object has no attribute 'status_code'"),
                self.request_operation(logger=self.logger, url="foo", method="unknown"),
            )
        self.assertIn(
            "ERROR:test_a2c:Request_operation returned error: 'NoneType' object has no attribute 'status_code'",
            lcm.output,
        )
        self.assertFalse(mock_get.called)
        self.assertFalse(mock_post.called)
        self.assertFalse(mock_put.called)

    def test_402_enrollment_config_log(self):
        """test enrollment_config_log()"""

        class myclass:
            pass

        myclass.foo = "foo_val"
        myclass.bar = "bar_val"
        myclass.password = "password_val"
        myclass.secret = "secret_val"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.enrollment_config_log(self.logger, myclass))
        self.assertIn(
            "INFO:test_a2c:Enrollment configuration: ['foo: foo_val', 'bar: bar_val']",
            lcm.output,
        )

    def test_403_enrollment_config_log(self):
        """test enrollment_config_log()"""

        class myclass:
            pass

        myclass.foo = "foo_val"
        myclass.bar = "bar_val"
        myclass.foobar = "foobar_val"
        myclass.password = "password_val"
        myclass.secret = "secret_val"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(
                self.enrollment_config_log(self.logger, myclass, ["foo", "bar"])
            )
        self.assertIn(
            "INFO:test_a2c:Enrollment configuration: ['foobar: foobar_val']", lcm.output
        )

    def test_404_enrollment_config_log(self):
        """test enrollment_config_log()"""

        class myclass:
            pass

        myclass.foo = "foo_val"
        myclass.bar = "bar_val"
        myclass.foobar = "foobar_val"
        myclass.password = "password_val"
        myclass.secret = "secret_val"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(
                self.enrollment_config_log(self.logger, myclass, "failed to parse")
            )
        self.assertIn(
            "ERROR:test_a2c:Enrollment configuration won't get logged due to a configuration error.",
            lcm.output,
        )

    def test_405_config_enroll_config_log_load(self):
        """test config_enroll_config_log_load()"""
        config_dic = configparser.ConfigParser()
        config_dic["CAhandler"] = {"enrollment_config_log": "True"}
        self.assertEqual(
            (True, []), self.config_enroll_config_log_load(self.logger, config_dic)
        )

    def test_406_config_enroll_config_log_load(self):
        """test config_enroll_config_log_load()"""
        config_dic = configparser.ConfigParser()
        config_dic["CAhandler"] = {"enrollment_config_log": "False"}
        self.assertEqual(
            (False, []), self.config_enroll_config_log_load(self.logger, config_dic)
        )

    def test_407_config_enroll_config_log_load(self):
        """test config_enroll_config_log_load()"""
        config_dic = configparser.ConfigParser()
        config_dic["CAhandler"] = {"enrollment_config_log": "aaa"}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (False, []), self.config_enroll_config_log_load(self.logger, config_dic)
            )
        self.assertIn(
            "WARNING:test_a2c:Failed to load enrollment_config_log from configuration: Not a boolean: aaa",
            lcm.output,
        )

    def test_408_config_enroll_config_log_load(self):
        """test config_enroll_config_log_load()"""
        config_dic = configparser.ConfigParser()
        config_dic["CAhandler"] = {
            "enrollment_config_log": "True",
            "enrollment_config_log_skip_list": '["foo", "bar"]',
        }
        self.assertEqual(
            (True, ["foo", "bar"]),
            self.config_enroll_config_log_load(self.logger, config_dic),
        )

    def test_409_config_enroll_config_log_load(self):
        """test config_enroll_config_log_load()"""
        config_dic = configparser.ConfigParser()
        config_dic["CAhandler"] = {
            "enrollment_config_log": "True",
            "enrollment_config_log_skip_list": '"foo",',
        }
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                (True, "failed to parse"),
                self.config_enroll_config_log_load(self.logger, config_dic),
            )
        self.assertIn(
            "WARNING:test_a2c:Failed to parse enrollment_config_log_skip_list from configuration: Extra data: line 1 column 6 (char 5)",
            lcm.output,
        )

    def test_410_config_allowed_domainlist_load(self):
        """test config_allowed_domainlist_load()"""
        config_dic = {"CAhandler": {"allowed_domainlist": '["foo", "bar", "foobar"]'}}
        self.assertEqual(
            ["foo", "bar", "foobar"],
            self.config_allowed_domainlist_load(self.logger, config_dic),
        )

    def test_411_config_allowed_domainlist_load(self):
        """test config_allowed_domainlist_load()"""
        config_dic = {"CAhandler": {"allowed_domainlist": '["foo"]'}}
        self.assertEqual(
            ["foo"], self.config_allowed_domainlist_load(self.logger, config_dic)
        )

    def test_412_config_allowed_domainlist_load(self):
        """test config_allowed_domainlist_load()"""
        config_dic = {"CAhandler": {"allowed_domainlist": "foo"}}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                "failed to parse",
                self.config_allowed_domainlist_load(self.logger, config_dic),
            )
        self.assertIn(
            "WARNING:test_a2c:Failed to load allowed_domainlist from configuration: Expecting value: line 1 column 1 (char 0)",
            lcm.output,
        )

    def test_413_domainlist_check(self):
        """domainlist_check failed check as empty entry"""
        list_ = ["bar.foo", "foo.bar"]
        entry = None
        self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_414_is_domain_whitelisted(self):
        """is_domain_whitelisted failed check as empty entry"""
        list_ = ["bar.foo$", "foo.bar$"]
        entry = None
        self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_415_is_domain_whitelisted(self):
        """is_domain_whitelisted check against empty list"""
        list_ = []
        entry = "host.bar.foo"
        self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_416_is_domain_whitelisted(self):
        """is_domain_whitelisted successful check against 1st element of a list"""
        list_ = ["*.bar.foo", "*.foo.bar"]
        entry = "host.bar.foo"
        self.assertTrue(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_417_is_domain_whitelisted(self):
        """is_domain_whitelisted unsuccessful as endcheck failed"""
        list_ = ["bar.foo", "foo.bar"]
        entry = "host.bar.foo.bar1"
        self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_418_is_domain_whitelisted(self):
        """is_domain_whitelisted wildcard check"""
        list_ = ["*.bar.foo", "foo.bar"]
        entry = "*.bar.foo"
        self.assertTrue(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_419_is_domain_whitelisted(self):
        """is_domain_whitelisted failed wildcard check"""
        list_ = ["bar.foo$", "foo.bar$"]
        entry = "*.bar.foo_"
        self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_420_is_domain_whitelisted(self):
        """is_domain_whitelisted not end check"""
        list_ = ["bar.foo$", "foo.bar$"]
        entry = "bar.foo gna"
        self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_421_is_domain_whitelisted(self):
        """is_domain_whitelisted $ at the end"""
        list_ = ["bar.foo$", "foo.bar$"]
        entry = "bar.foo$"
        self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_422_is_domain_whitelisted(self):
        """is_domain_whitelisted unsuccessful whildcard check"""
        list_ = ["foo.bar$", r"\*.bar.foo"]
        entry = "host.bar.foo"
        self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_423_is_domain_whitelisted(self):
        """is_domain_whitelisted successful whildcard check"""
        list_ = ["foo.bar$", r"*.bar.foo"]
        entry = "*.bar.foo"
        self.assertTrue(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_424_is_domain_whitelisted(self):
        """is_domain_whitelisted successful whildcard in list but not in string"""
        list_ = ["foo.bar$", "*.bar.foo"]
        entry = "foo.bar.foo"
        self.assertTrue(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_425_is_domain_whitelisted(self):
        """ip address check NOne in whitelist"""
        list_ = [None, "*.bar.foo"]
        entry = "foo.bar.foo"
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertTrue(self.is_domain_whitelisted(self.logger, entry, list_))
        self.assertIn(
            "ERROR:test_a2c:Invalid pattern configured in allowed_domainlist: empty string",
            lcm.output,
        )

    @patch("idna.encode")
    def test_426_is_domain_whitelisted(self, mock_idna):
        """exception"""
        list_ = ["example.com", "*.bar.foo"]
        entry = "foo.bar.foo"
        mock_idna.side_effect = Exception("idna error")
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))
        self.assertIn(
            "ERROR:test_a2c:Invalid domain format in csr: idna error", lcm.output
        )

    def test_427_is_domain_whitelisted(self):
        """whitelist"""
        list_ = ["example.com", "bar.foo"]
        entry = "*.bar.foo"
        self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_428_is_domain_whitelisted(self):
        """exact domain name"""
        list_ = ["example.com", "bar.foo"]
        entry = "bar.foo"
        self.assertTrue(self.is_domain_whitelisted(self.logger, entry, list_))

    def test_429_is_domain_whitelisted(self):
        """wildcard domain name"""
        list_ = ["*.example.com", "*.bar.foo"]
        entry = "*.example.com"
        self.assertTrue(self.is_domain_whitelisted(self.logger, entry, list_))

    @patch("idna.encode")
    def test_430_is_domain_whitelisted(self, mock_idna):
        """exception"""
        list_ = ["example.com", "*.bar.foo"]
        entry = "foo.bar.foo"
        mock_idna.side_effect = [Exception("idna error"), "bar"]
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.is_domain_whitelisted(self.logger, entry, list_))
        self.assertIn(
            "ERROR:test_a2c:Invalid pattern configured in allowed_domainlist: *.bar.foo",
            lcm.output,
        )

    @patch("acme2certifier.acme_srv.helpers.domain_utils.csr_cn_get")
    @patch("acme2certifier.acme_srv.helpers.domain_utils.csr_san_get")
    def test_431_allowed_domainlist_check(self, mock_san, mock_cn):
        """CAhandler._check_csr with empty allowed_domainlist"""
        allowed_domainlist = []
        mock_san.return_value = ["DNS:host.foo.bar"]
        mock_cn.return_value = "host2.foo.bar"
        csr = "csr"
        self.assertFalse(
            self.allowed_domainlist_check(self.logger, csr, allowed_domainlist)
        )

    @patch("acme2certifier.acme_srv.helpers.domain_utils.csr_cn_get")
    @patch("acme2certifier.acme_srv.helpers.domain_utils.csr_san_get")
    def test_432_allowed_domainlist_check(self, mock_san, mock_cn):
        """CAhandler._check_csr with empty allowed_domainlist"""
        allowed_domainlist = ["*.foo.bar"]
        mock_san.return_value = ["DNS:host.foo.bar"]
        mock_cn.return_value = "host2.foo.bar"
        csr = "csr"
        self.assertFalse(
            self.allowed_domainlist_check(self.logger, csr, allowed_domainlist)
        )

    @patch("acme2certifier.acme_srv.helpers.domain_utils.csr_cn_get")
    @patch("acme2certifier.acme_srv.helpers.domain_utils.csr_san_get")
    def test_433_allowed_domainlist_check(self, mock_san, mock_cn):
        """CAhandler._check_csr with allowd allowed_domainlist"""
        allowed_domainlist = ["*.bar.bar"]
        mock_san.return_value = ["DNS:host.foo.bar"]
        mock_cn.return_value = "host2.foo.bar"
        csr = "csr"
        self.assertEqual(
            "Either CN or SANs are not allowed by configuration",
            self.allowed_domainlist_check(self.logger, csr, allowed_domainlist),
        )

    @patch("acme2certifier.acme_srv.helpers.domain_utils.csr_cn_get")
    @patch("acme2certifier.acme_srv.helpers.domain_utils.csr_san_get")
    def test_434_allowed_domainlist_check(self, mock_san, mock_cn):
        """CAhandler._check_csr with allowed allowed_domainlist"""
        allowed_domainlist = ["*.foo.bar"]
        mock_san.return_value = ["invalidhostname"]
        mock_cn.return_value = "host2.foo.bar"
        csr = "csr"
        self.assertEqual(
            "SAN list parsing failed ['invalidhostname']",
            self.allowed_domainlist_check(self.logger, csr, allowed_domainlist),
        )

    @patch("acme2certifier.acme_srv.helpers.domain_utils.csr_cn_get")
    @patch("acme2certifier.acme_srv.helpers.domain_utils.csr_san_get")
    def test_435_allowed_domainlist_check(self, mock_san, mock_cn):
        """CAhandler._check_csr with empty allowed_domainlist"""
        allowed_domainlist = ["*.foo.bar"]
        mock_san.return_value = ["email:user@bar.foo.bar"]
        mock_cn.return_value = "host2.foo.bar"
        csr = "csr"
        self.assertFalse(
            self.allowed_domainlist_check(self.logger, csr, allowed_domainlist)
        )

    @patch("random.randint")
    def test_436_radomize_parameter_list(self, mock_rand):
        """test radomize_parameter_list()"""

        class myclass:
            pass

        myclass.foo = "foo1, foo2, foo2"
        myclass.bar = "bar1, bar2, bar3"
        self.radomize_parameter_list(self.logger, myclass, ["foo", "bar"])
        self.assertEqual("foo2", myclass.foo)
        self.assertEqual("bar2", myclass.bar)

    @patch("random.randint")
    def test_437_radomize_parameter_list(self, mock_rand):
        """test radomize_parameter_list()"""

        class myclass:
            pass

        myclass.foo = "foo1, foo2, foo2"
        myclass.bar = "bar1, bar2, bar3"
        self.radomize_parameter_list(self.logger, myclass, ["foo1", "bar"])
        self.assertEqual("foo1, foo2, foo2", myclass.foo)
        self.assertEqual("bar2", myclass.bar)

    @patch("random.randint")
    def test_438_radomize_parameter_list(self, mock_rand):
        """test radomize_parameter_list()"""

        class myclass:
            pass

        myclass.foo = "foo1"
        myclass.bar = "bar1"
        self.radomize_parameter_list(self.logger, myclass, ["foo1", "bar"])
        self.assertEqual("foo1", myclass.foo)
        self.assertEqual("bar1", myclass.bar)

    def test_439_config_profile_load(self):
        """test _config_load with unknown values config"""
        parser = configparser.ConfigParser()
        parser["Order"] = {"profiles": '{"foo": "bar", "bar": "foo"}'}
        self.assertEqual(
            {"foo": "bar", "bar": "foo"}, self.config_profile_load(self.logger, parser)
        )

    def test_440_config_profile_load(self):
        """test _config_load with unknown values config"""
        parser = configparser.ConfigParser()
        parser["Order"] = {"profiles": "foo"}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.config_profile_load(self.logger, parser))
        self.assertIn(
            "WARNING:test_a2c:Failed to load profiles from configuration: Expecting value: line 1 column 1 (char 0)",
            lcm.output,
        )

    def test_441_profile_lookup(self):
        """profile_lookup ()"""
        models_mock = MagicMock()
        models_mock.DBstore().certificates_search.return_value = [
            {"foo": "bar", "order__profile": "order_profile"}
        ]
        modules = {"acme2certifier.acme_srv.db_handler": models_mock}
        patch.dict("sys.modules", modules).start()
        self.assertEqual("order_profile", self.profile_lookup(self.logger, "csr"))

    def test_442_profile_lookup(self):
        """profile_lookup ()"""
        models_mock = MagicMock()
        models_mock.DBstore().certificates_search.return_value = None
        modules = {"acme2certifier.acme_srv.db_handler": models_mock}
        patch.dict("sys.modules", modules).start()
        self.assertFalse(self.profile_lookup(self.logger, "csr"))

    def test_443_profile_lookup(self):
        """profile_lookup ()"""
        models_mock = MagicMock()
        models_mock.DBstore().certificates_search.return_value = [{"foo": "bar"}]
        modules = {"acme2certifier.acme_srv.db_handler": models_mock}
        patch.dict("sys.modules", modules).start()
        self.assertFalse(self.profile_lookup(self.logger, "csr"))

    def test_444_profile_lookup(self):
        """profile_lookup ()"""
        models_mock = MagicMock()
        models_mock.DBstore().certificates_search.side_effect = Exception("mock_search")
        modules = {"acme2certifier.acme_srv.db_handler": models_mock}
        patch.dict("sys.modules", modules).start()
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertFalse(self.profile_lookup(self.logger, "csr"))
        self.assertIn(
            "WARNING:test_a2c:Profile lookup failed with: mock_search",
            lcm.output,
        )

    def test_445_b64_url_decode(self):
        """test b64_url_decode()"""
        self.assertEqual("foo", self.b64_url_decode(self.logger, "Zm9v"))

    def test_446_b64_url_decode(self):
        """test b64_url_decode()"""
        self.assertEqual(
            "thisisateststring",
            self.b64_url_decode(self.logger, "dGhpc2lzYXRlc3RzdHJpbmc"),
        )

    def test_447_b64_url_decode(self):
        """test b64_url_decode()"""
        self.assertEqual(
            "thisisateststring",
            self.b64_url_decode(self.logger, "dGhpc2lzYXRlc3RzdHJpbmc="),
        )

    def test_448_b64_url_decode(self):
        """test b64_url_decode()"""
        self.assertEqual(
            "thisisateststring",
            self.b64_url_decode(self.logger, "dGhpc2lzYXRlc3RzdHJpbmc    "),
        )

    @patch("acme2certifier.acme_srv.helpers.encoding.b64_url_recode", return_value="encoded_cert")
    def test_449_eab_profile_revocation_check_str_value(self, mock_b64_url_recode):
        """eab_profile_dic with a string value"""
        self.cahandler = MagicMock()
        self.cahandler.eab_handler.return_value.__enter__.return_value = MagicMock()
        self.certificate_raw = "dummy_cert"
        eab_handler = self.cahandler.eab_handler.return_value.__enter__.return_value
        eab_handler.eab_profile_get.return_value = {"profile": "value"}
        with patch(
            "acme2certifier.acme_srv.helpers.eab.eab_profile_string_check"
        ) as mock_string_check:
            self.eab_profile_revocation_check(
                self.logger, self.cahandler, self.certificate_raw
            )
            mock_string_check.assert_called_once_with(
                self.logger, self.cahandler, "profile", "value"
            )
            self.assertFalse(mock_b64_url_recode.called)

    @patch("acme2certifier.acme_srv.helpers.encoding.b64_url_recode", return_value="encoded_cert")
    def test_450_eab_profile_revocation_check_str_and_ignore_value(
        self, mock_b64_url_recode
    ):
        """eab_profile_dic with a string value"""
        self.cahandler = MagicMock()
        self.cahandler.eab_handler.return_value.__enter__.return_value = MagicMock()
        self.certificate_raw = "dummy_cert"
        eab_handler = self.cahandler.eab_handler.return_value.__enter__.return_value
        eab_handler.eab_profile_get.return_value = {
            "profile": "value",
            "subject": "value2",
        }
        with patch(
            "acme2certifier.acme_srv.helpers.eab.eab_profile_string_check"
        ) as mock_string_check:
            self.eab_profile_revocation_check(
                self.logger, self.cahandler, self.certificate_raw
            )
            mock_string_check.assert_called_once_with(
                self.logger, self.cahandler, "profile", "value"
            )
            self.assertFalse(mock_b64_url_recode.called)

    @patch("acme2certifier.acme_srv.helpers.encoding.b64_url_recode", return_value="encoded_cert")
    def test_451_eab_profile_revocation_check_list_value(self, mock_b64_url_recode):
        """eab_profile_dic with a list value"""
        self.cahandler = MagicMock()
        self.cahandler.eab_handler.return_value.__enter__.return_value = MagicMock()
        self.certificate_raw = "dummy_cert"
        eab_handler = self.cahandler.eab_handler.return_value.__enter__.return_value
        eab_handler.eab_profile_get.return_value = {"profile": ["v1", "v2"]}
        self.cahandler.eab_profile_list_check = MagicMock()
        self.eab_profile_revocation_check(
            self.logger, self.cahandler, self.certificate_raw
        )
        self.cahandler.eab_profile_list_check.assert_called_once()
        self.assertFalse(mock_b64_url_recode.called)

    @patch("acme2certifier.acme_srv.helpers.encoding.b64_url_recode", return_value="encoded_cert")
    def test_452_eab_profile_revocation_check_list_value_fallback(
        self, mock_b64_url_recode
    ):
        """eab_profile_dic with a list value, fallback to global function"""
        self.cahandler = MagicMock()
        self.cahandler.eab_handler.return_value.__enter__.return_value = MagicMock()
        self.certificate_raw = "dummy_cert"
        eab_handler = self.cahandler.eab_handler.return_value.__enter__.return_value
        eab_handler.eab_profile_get.return_value = {"profile": ["v1", "v2"]}
        if hasattr(self.cahandler, "eab_profile_list_check"):
            delattr(self.cahandler, "eab_profile_list_check")
        with patch("acme2certifier.acme_srv.helpers.eab.eab_profile_list_check") as mock_list_check:
            self.eab_profile_revocation_check(
                self.logger, self.cahandler, self.certificate_raw
            )
            mock_list_check.assert_called_once()

    def test_453_missing_required_keys(self):
        """test handler_config_check() with missing required keys"""

        class DummyHandler(object):
            def __init__(self):
                self.vault_url = "url"
                self.vault_token = None

        dummy_handler = DummyHandler()
        required_keys = ["vault_url", "vault_token"]
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                "vault_token parameter is missing in config file",
                self.handler_config_check(self.logger, dummy_handler, required_keys),
            )
        self.assertIn(
            "ERROR:test_a2c:Configuration check ended with error: vault_token parameter is missing in config file",
            lcm.output,
        )

    def test_454_all_required_keys_present(self):
        class DummyHandler(object):
            def __init__(self):
                self.vault_url = "url"
                self.vault_token = "token"
                self.another_param = "param"

        dummy_handler = DummyHandler()
        required_keys = ["vault_url", "vault_token"]
        self.assertFalse(
            self.handler_config_check(self.logger, dummy_handler, required_keys)
        )

    def test_455_empty_config(self):
        class DummyHandler(object):
            def __init__(self):
                self.vault_url = "url"
                self.vault_token = "token"

        dummy_handler = DummyHandler()
        required_keys = []
        self.assertFalse(
            self.handler_config_check(self.logger, dummy_handler, required_keys)
        )

    @patch("acme2certifier.acme_srv.helpers.network.proxy_check")
    @patch("acme2certifier.acme_srv.helpers.network.parse_url")
    def test_456_config_proxy_load_valid_config(self, mock_parse_url, mock_proxy_check):
        """test config_proxy_load() with valid configuration"""
        config_dic = {
            "DEFAULT": {
                "proxy_server_list": '{"example.com": "proxy.example.com:8080", "*.test.com": "proxy.test.com:3128"}'
            }
        }
        host_name = "https://api.example.com:443/test"

        # Mock parse_url to return host information
        mock_parse_url.return_value = {"host": "api.example.com:443"}
        # Mock proxy_check to return a proxy server
        mock_proxy_check.return_value = "proxy.example.com:8080"

        result = self.config_proxy_load(self.logger, config_dic, host_name)

        expected = {"http": "proxy.example.com:8080", "https": "proxy.example.com:8080"}
        self.assertEqual(result, expected)

        # Verify the mocks were called correctly
        mock_parse_url.assert_called_once_with(self.logger, host_name)
        mock_proxy_check.assert_called_once_with(
            self.logger,
            "api.example.com",
            {
                "example.com": "proxy.example.com:8080",
                "*.test.com": "proxy.test.com:3128",
            },
        )

    def test_457_config_proxy_load_no_default_section(self):
        """test config_proxy_load() with no DEFAULT section"""
        config_dic = {"OTHER": {"some_setting": "value"}}
        host_name = "https://api.example.com:443/test"

        result = self.config_proxy_load(self.logger, config_dic, host_name)

        self.assertEqual(result, {})

    def test_458_config_proxy_load_no_proxy_server_list(self):
        """test config_proxy_load() with no proxy_server_list in DEFAULT section"""
        config_dic = {"DEFAULT": {"other_setting": "value"}}
        host_name = "https://api.example.com:443/test"

        result = self.config_proxy_load(self.logger, config_dic, host_name)

        self.assertEqual(result, {})

    def test_459_config_proxy_load_invalid_json(self):
        """test config_proxy_load() with invalid JSON in proxy_server_list"""
        config_dic = {"DEFAULT": {"proxy_server_list": "invalid json string"}}
        host_name = "https://api.example.com:443/test"

        with self.assertLogs("test_a2c", level="INFO") as lcm:
            result = self.config_proxy_load(self.logger, config_dic, host_name)

        self.assertEqual(result, {})
        # Check that warning message was logged
        self.assertTrue(
            any(
                "Failed to parse proxy_server_list from configuration:" in log
                for log in lcm.output
            )
        )

    @patch("acme2certifier.acme_srv.helpers.network.parse_url")
    def test_460_config_proxy_load_no_host_in_url(self, mock_parse_url):
        """test config_proxy_load() with parsed URL missing host information"""
        config_dic = {
            "DEFAULT": {
                "proxy_server_list": '{"example.com": "proxy.example.com:8080"}'
            }
        }
        host_name = "invalid-url"

        # Mock parse_url to return empty dict (no host)
        mock_parse_url.return_value = {}

        result = self.config_proxy_load(self.logger, config_dic, host_name)

        self.assertEqual(result, {})
        mock_parse_url.assert_called_once_with(self.logger, host_name)

    @patch("acme2certifier.acme_srv.helpers.network.proxy_check")
    @patch("acme2certifier.acme_srv.helpers.network.parse_url")
    def test_461_config_proxy_load_proxy_check_returns_none(
        self, mock_parse_url, mock_proxy_check
    ):
        """test config_proxy_load() when proxy_check returns None"""
        config_dic = {
            "DEFAULT": {"proxy_server_list": '{"other.com": "proxy.other.com:8080"}'}
        }
        host_name = "https://api.example.com:443/test"

        # Mock parse_url to return host information
        mock_parse_url.return_value = {"host": "api.example.com:443"}
        # Mock proxy_check to return None (no proxy needed)
        mock_proxy_check.return_value = None

        result = self.config_proxy_load(self.logger, config_dic, host_name)

        expected = {"http": None, "https": None}
        self.assertEqual(result, expected)

    @patch("acme2certifier.acme_srv.helpers.network.parse_url")
    def test_462_config_proxy_load_parse_url_exception(self, mock_parse_url):
        """test config_proxy_load() when parse_url raises exception"""
        config_dic = {
            "DEFAULT": {
                "proxy_server_list": '{"example.com": "proxy.example.com:8080"}'
            }
        }
        host_name = "https://api.example.com:443/test"

        # Mock parse_url to raise an exception
        mock_parse_url.side_effect = Exception("URL parsing error")

        with self.assertLogs("test_a2c", level="INFO") as lcm:
            result = self.config_proxy_load(self.logger, config_dic, host_name)

        self.assertEqual(result, {})
        # Check that warning message was logged
        self.assertTrue(
            any(
                "Failed to parse proxy_server_list from configuration: URL parsing error"
                in log
                for log in lcm.output
            )
        )

    @patch("acme2certifier.acme_srv.helpers.network.proxy_check")
    @patch("acme2certifier.acme_srv.helpers.network.parse_url")
    def test_463_config_proxy_load_host_without_port(
        self, mock_parse_url, mock_proxy_check
    ):
        """test config_proxy_load() with host that doesn't contain port"""
        config_dic = {
            "DEFAULT": {
                "proxy_server_list": '{"example.com": "proxy.example.com:8080"}'
            }
        }
        host_name = "https://api.example.com/test"

        # Mock parse_url to return host without port
        mock_parse_url.return_value = {"host": "api.example.com"}
        # Mock proxy_check to return a proxy server
        mock_proxy_check.return_value = "proxy.example.com:8080"

        # This should cause an exception when trying to split on ':'
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            result = self.config_proxy_load(self.logger, config_dic, host_name)

        self.assertEqual(result, {})
        # Check that warning message was logged due to the exception
        self.assertTrue(
            any(
                "Failed to parse proxy_server_list from configuration:" in log
                for log in lcm.output
            )
        )

    @patch("acme2certifier.acme_srv.helpers.network.proxy_check")
    @patch("acme2certifier.acme_srv.helpers.network.parse_url")
    def test_464_config_proxy_load_empty_proxy_list(
        self, mock_parse_url, mock_proxy_check
    ):
        """test config_proxy_load() with empty proxy_server_list"""
        config_dic = {"DEFAULT": {"proxy_server_list": "{}"}}
        host_name = "https://api.example.com:443/test"

        # Mock parse_url to return host information
        mock_parse_url.return_value = {"host": "api.example.com:443"}
        # Mock proxy_check to return None for empty proxy list
        mock_proxy_check.return_value = None

        result = self.config_proxy_load(self.logger, config_dic, host_name)

        expected = {"http": None, "https": None}
        self.assertEqual(result, expected)

        mock_parse_url.assert_called_once_with(self.logger, host_name)
        mock_proxy_check.assert_called_once_with(self.logger, "api.example.com", {})

    def test_465_config_async_mode_load_true_with_django(self):
        """test config_async_mode_load() with async_mode True and django db"""
        config_dic = configparser.ConfigParser()
        config_dic["DEFAULT"] = {"async_mode": "True"}
        db_type = "django"
        result = self.config_async_mode_load(self.logger, config_dic, db_type)
        self.assertTrue(result)

    def test_466_config_async_mode_load_true_non_django(self):
        """test config_async_mode_load() with async_mode True and non-django db"""
        config_dic = configparser.ConfigParser()
        config_dic["DEFAULT"] = {"async_mode": "True"}
        db_type = "sqlite"
        with self.assertLogs(self.logger, level="INFO") as log:
            result = self.config_async_mode_load(self.logger, config_dic, db_type)
        self.assertFalse(result)
        self.assertIn("asynchronous Challenge validation disabled", log.output[0])

    def test_467_config_async_mode_load_false_with_django(self):
        """test config_async_mode_load() with async_mode False and django db"""
        config_dic = configparser.ConfigParser()
        config_dic["DEFAULT"] = {"async_mode": "False"}
        db_type = "django"
        self.assertFalse(self.config_async_mode_load(self.logger, config_dic, db_type))

    def test_468_config_async_mode_load_default_fallback(self):
        """test config_async_mode_load() with no async_mode setting (fallback)"""
        config_dic = configparser.ConfigParser()
        config_dic["DEFAULT"] = {}
        db_type = "django"
        self.assertFalse(self.config_async_mode_load(self.logger, config_dic, db_type))

    def test_469_config_async_mode_load_no_default_section(self):
        """test config_async_mode_load() with no DEFAULT section"""
        config_dic = configparser.ConfigParser()
        db_type = "django"
        self.assertFalse(self.config_async_mode_load(self.logger, config_dic, db_type))

    def test_470_config_async_mode_load_invalid_boolean(self):
        """test config_async_mode_load() with invalid boolean value"""
        config_dic = configparser.ConfigParser()
        config_dic["DEFAULT"] = {"async_mode": "invalid"}
        db_type = "django"
        # Invalid boolean values should raise a ValueError by getboolean()
        with self.assertRaises(ValueError) as context:
            self.config_async_mode_load(self.logger, config_dic, db_type)
        self.assertIn("Not a boolean: invalid", str(context.exception))

    def test_471_config_async_mode_load_case_insensitive_true(self):
        """test config_async_mode_load() with case insensitive True values"""
        test_cases = ["true", "TRUE", "True", "1", "yes", "on"]
        for value in test_cases:
            with self.subTest(value=value):
                config_dic = configparser.ConfigParser()
                config_dic["DEFAULT"] = {"async_mode": value}
                db_type = "django"
                result = self.config_async_mode_load(self.logger, config_dic, db_type)
                self.assertTrue(result)

    def test_472_config_async_mode_load_case_insensitive_false(self):
        """test config_async_mode_load() with case insensitive False values"""
        test_cases = ["false", "FALSE", "False", "0", "no", "off"]
        for value in test_cases:
            with self.subTest(value=value):
                config_dic = configparser.ConfigParser()
                config_dic["DEFAULT"] = {"async_mode": value}
                db_type = "django"
                self.assertFalse(
                    self.config_async_mode_load(self.logger, config_dic, db_type)
                )

    def test_473_config_async_mode_load_different_db_types(self):
        """test config_async_mode_load() with various non-django db types"""
        config_dic = configparser.ConfigParser()
        config_dic["DEFAULT"] = {"async_mode": "True"}

        db_types = ["sqlite", "mysql", "postgresql", "oracle", "wsgi", ""]
        for db_type in db_types:
            with self.subTest(db_type=db_type):
                with self.assertLogs(self.logger, level="INFO") as log:
                    result = self.config_async_mode_load(
                        self.logger, config_dic, db_type
                    )
                self.assertFalse(result)
                self.assertIn(
                    "asynchronous Challenge validation disabled", log.output[0]
                )

    def test_474_fqdn_resolve_successful_a_record_no_catch_all(self):
        """Test successful A record resolution without catch_all"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        # Create a proper mock that behaves like dns.resolver answer
        mock_answer = [Mock(__str__=Mock(return_value="192.168.1.1"))]
        mock_resolver.resolve.return_value = mock_answer

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=False
        )

        self.assertEqual(result, "192.168.1.1")
        self.assertFalse(invalid)
        self.assertIsNone(error_msg)
        mock_resolver.resolve.assert_called_once_with("example.com", "A")

    def test_475_fqdn_resolve_successful_aaaa_record_no_catch_all(self):
        """Test successful AAAA record resolution when A record fails"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()

        # A record fails, AAAA succeeds
        mock_aaaa_answer = [Mock(__str__=Mock(return_value="2001:db8::1"))]
        mock_resolver.resolve.side_effect = [dns.resolver.NXDOMAIN(), mock_aaaa_answer]

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=False
        )

        self.assertEqual(result, "2001:db8::1")
        self.assertFalse(invalid)
        self.assertIsNone(error_msg)

    def test_476_fqdn_resolve_successful_catch_all_both_records(self):
        """Test successful resolution with catch_all returning both A and AAAA"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()

        # Mock both A and AAAA responses
        mock_a_answer = [
            Mock(__str__=Mock(return_value="192.168.1.1")),
            Mock(__str__=Mock(return_value="192.168.1.2")),
        ]
        mock_aaaa_answer = [Mock(__str__=Mock(return_value="2001:db8::1"))]
        mock_resolver.resolve.side_effect = [mock_a_answer, mock_aaaa_answer]

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=True
        )

        self.assertEqual(result, ["192.168.1.1", "192.168.1.2", "2001:db8::1"])
        self.assertFalse(invalid)
        self.assertIsNone(error_msg)

    def test_477_fqdn_resolve_nxdomain_error(self):
        """Test NXDOMAIN error handling"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_resolver.resolve.side_effect = dns.resolver.NXDOMAIN()

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "nonexistent.com", catch_all=False
        )

        expected_result = None
        self.assertEqual(result, expected_result)
        self.assertTrue(invalid)
        self.assertIn("NXDOMAIN: nonexistent.com does not exist", error_msg)

    def test_478_fqdn_resolve_no_answer_error(self):
        """Test NoAnswer error handling"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_resolver.resolve.side_effect = dns.resolver.NoAnswer()

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=False
        )

        expected_result = None
        self.assertEqual(result, expected_result)
        self.assertTrue(invalid)
        self.assertIn("No A record found for example.com", error_msg)

    def test_479_fqdn_resolve_timeout_error(self):
        """Test timeout error handling"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_resolver.resolve.side_effect = dns.resolver.Timeout()

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=False
        )

        expected_result = None
        self.assertEqual(result, expected_result)
        self.assertTrue(invalid)
        self.assertIn("DNS query timeout for example.com", error_msg)

    def test_480_fqdn_resolve_generic_error(self):
        """Test generic exception handling"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_resolver.resolve.side_effect = Exception("Connection refused")

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=False
        )

        expected_result = None
        self.assertEqual(result, expected_result)
        self.assertTrue(invalid)
        self.assertIn("DNS resolution error: Connection refused", error_msg)

    def test_481_fqdn_resolve_mixed_errors_catch_all(self):
        """Test mixed errors across record types with catch_all"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_resolver.resolve.side_effect = [
            dns.resolver.NXDOMAIN(),  # A record fails
            dns.resolver.Timeout(),  # AAAA record fails
        ]

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=True
        )

        expected_result = []
        self.assertEqual(result, expected_result)
        self.assertTrue(invalid)
        self.assertIn("A: NXDOMAIN: example.com does not exist", error_msg)
        self.assertIn("AAAA: DNS query timeout for example.com", error_msg)

    def test_482_fqdn_resolve_empty_answers_no_catch_all(self):
        """Test empty answers without catch_all"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_answer = []  # Empty list - no DNS records
        mock_resolver.resolve.return_value = mock_answer

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=False
        )

        expected_result = None
        self.assertEqual(result, expected_result)
        self.assertTrue(invalid)
        self.assertIsNone(error_msg)

    def test_483_fqdn_resolve_empty_answers_catch_all(self):
        """Test empty answers with catch_all"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_answer = []  # Empty list - no DNS records
        mock_resolver.resolve.return_value = mock_answer

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=True
        )

        expected_result = []
        self.assertEqual(result, expected_result)
        self.assertTrue(invalid)
        self.assertIsNone(error_msg)

    def test_484_fqdn_resolve_partial_success_catch_all(self):
        """Test partial success with catch_all (A succeeds, AAAA fails)"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_a_answer = [Mock(__str__=Mock(return_value="192.168.1.1"))]
        mock_resolver.resolve.side_effect = [
            mock_a_answer,  # A record succeeds
            dns.resolver.NoAnswer(),  # AAAA record fails
        ]

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=True
        )

        self.assertEqual(result, ["192.168.1.1"])
        self.assertFalse(invalid)  # Should be valid since at least one succeeded
        self.assertIsNone(error_msg)

    def test_485_fqdn_resolve_multiple_a_records_no_catch_all(self):
        """Test multiple A records without catch_all (should return first)"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_answer = [
            Mock(__str__=Mock(return_value="192.168.1.1")),
            Mock(__str__=Mock(return_value="192.168.1.2")),
            Mock(__str__=Mock(return_value="192.168.1.3")),
        ]
        mock_resolver.resolve.return_value = mock_answer

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=False
        )

        self.assertEqual(result, "192.168.1.1")
        self.assertFalse(invalid)
        self.assertIsNone(error_msg)
        # Should only make one call since it breaks after first success
        mock_resolver.resolve.assert_called_once_with("example.com", "A")

    def test_486_fqdn_resolve_a_fails_aaaa_succeeds_no_catch_all(self):
        """Test A record failure but AAAA success without catch_all"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_aaaa_answer = [Mock(__str__=Mock(return_value="2001:db8::1"))]
        mock_resolver.resolve.side_effect = [
            dns.resolver.NoAnswer(),  # A record fails
            mock_aaaa_answer,  # AAAA record succeeds
        ]

        result, invalid, error_msg = _fqdn_resolve(
            self.logger, mock_resolver, "example.com", catch_all=False
        )

        self.assertEqual(result, "2001:db8::1")
        self.assertFalse(invalid)
        self.assertIsNone(error_msg)

    def test_487_fqdn_resolve_logging_verification(self):
        """Test that appropriate logging occurs"""
        from acme2certifier.acme_srv.helpers.network import _fqdn_resolve

        mock_resolver = Mock()
        mock_answer = [Mock(__str__=Mock(return_value="192.168.1.1"))]
        mock_resolver.resolve.return_value = mock_answer

        with self.assertLogs(self.logger, level="DEBUG") as log_context:
            result, invalid, error_msg = _fqdn_resolve(
                self.logger, mock_resolver, "example.com", catch_all=False
            )

        self.assertEqual(result, "192.168.1.1")
        self.assertFalse(invalid)
        self.assertIsNone(error_msg)

        # Verify debug logs
        self.assertTrue(
            any(
                "Helper._fqdn_resolve(example.com:False)" in record.message
                for record in log_context.records
            )
        )
        self.assertTrue(
            any(
                "Helper._fqdn_resolve() got answer:" in record.message
                for record in log_context.records
            )
        )
        self.assertTrue(
            any(
                "Helper._fqdn_resolve(example.com) ended with:" in record.message
                for record in log_context.records
            )
        )

    def test_488_ptr_resolve_successful_resolution(self):
        """Test successful PTR record resolution"""
        from acme2certifier.acme_srv.helpers.network import ptr_resolve

        with patch("dns.resolver.Resolver") as mock_resolver_class:
            mock_resolver = Mock()
            mock_resolver_class.return_value = mock_resolver

            # Mock successful PTR resolution
            mock_ptr_answer = [Mock(__str__=Mock(return_value="example.com."))]
            mock_resolver.resolve.return_value = mock_ptr_answer

            with patch("dns.reversename.from_address") as mock_reverse:
                mock_reverse.return_value = "reversed_ip"

                result, invalid = ptr_resolve(self.logger, "192.168.1.1")

                self.assertEqual(result, "example.com")  # Trailing dot removed
                self.assertFalse(invalid)
                mock_reverse.assert_called_once_with("192.168.1.1")
                mock_resolver.resolve.assert_called_once_with("reversed_ip", "PTR")

    def test_489_ptr_resolve_successful_with_dns_servers(self):
        """Test successful PTR resolution with custom DNS servers"""
        from acme2certifier.acme_srv.helpers.network import ptr_resolve

        with patch("dns.resolver.Resolver") as mock_resolver_class:
            mock_resolver = Mock()
            mock_resolver_class.return_value = mock_resolver

            # Mock successful PTR resolution
            mock_ptr_answer = [Mock(__str__=Mock(return_value="mail.example.com."))]
            mock_resolver.resolve.return_value = mock_ptr_answer

            with patch("dns.reversename.from_address") as mock_reverse:
                mock_reverse.return_value = "reversed_ip"
                dns_servers = ["8.8.8.8", "1.1.1.1"]

                result, invalid = ptr_resolve(self.logger, "203.0.113.5", dns_servers)

                self.assertEqual(result, "mail.example.com")
                self.assertFalse(invalid)
                self.assertEqual(mock_resolver.nameservers, dns_servers)

    def test_490_ptr_resolve_exception_handling(self):
        """Test PTR resolution exception handling"""
        from acme2certifier.acme_srv.helpers.network import ptr_resolve

        with patch("dns.resolver.Resolver") as mock_resolver_class:
            mock_resolver = Mock()
            mock_resolver_class.return_value = mock_resolver
            mock_resolver.resolve.side_effect = Exception("DNS resolution failed")

            with patch("dns.reversename.from_address") as mock_reverse:
                mock_reverse.return_value = "reversed_ip"

                result, invalid = ptr_resolve(self.logger, "invalid.ip")

                self.assertIsNone(result)
                self.assertTrue(invalid)

    def test_491_ptr_resolve_nxdomain_error(self):
        """Test PTR resolution with NXDOMAIN error"""
        from acme2certifier.acme_srv.helpers.network import ptr_resolve

        with patch("dns.resolver.Resolver") as mock_resolver_class:
            mock_resolver = Mock()
            mock_resolver_class.return_value = mock_resolver
            mock_resolver.resolve.side_effect = dns.resolver.NXDOMAIN()

            with patch("dns.reversename.from_address") as mock_reverse:
                mock_reverse.return_value = "reversed_ip"

                result, invalid = ptr_resolve(self.logger, "10.0.0.1")

                self.assertIsNone(result)
                self.assertTrue(invalid)

    def test_492_ptr_resolve_timeout_error(self):
        """Test PTR resolution with timeout error"""
        from acme2certifier.acme_srv.helpers.network import ptr_resolve

        with patch("dns.resolver.Resolver") as mock_resolver_class:
            mock_resolver = Mock()
            mock_resolver_class.return_value = mock_resolver
            mock_resolver.resolve.side_effect = dns.resolver.Timeout()

            with patch("dns.reversename.from_address") as mock_reverse:
                mock_reverse.return_value = "reversed_ip"

                result, invalid = ptr_resolve(self.logger, "172.16.0.1")

                self.assertIsNone(result)
                self.assertTrue(invalid)

    def test_493_ptr_resolve_invalid_address_format(self):
        """Test PTR resolution with invalid IP address format"""
        from acme2certifier.acme_srv.helpers.network import ptr_resolve

        with patch("dns.resolver.Resolver") as mock_resolver_class:
            mock_resolver = Mock()
            mock_resolver_class.return_value = mock_resolver

            with patch("dns.reversename.from_address") as mock_reverse:
                mock_reverse.side_effect = Exception("Invalid IP address format")

                result, invalid = ptr_resolve(self.logger, "not.an.ip.address")

                self.assertIsNone(result)
                self.assertTrue(invalid)

    def test_494_ptr_resolve_empty_response(self):
        """Test PTR resolution with empty response"""
        from acme2certifier.acme_srv.helpers.network import ptr_resolve

        with patch("dns.resolver.Resolver") as mock_resolver_class:
            mock_resolver = Mock()
            mock_resolver_class.return_value = mock_resolver
            mock_resolver.resolve.side_effect = IndexError("list index out of range")

            with patch("dns.reversename.from_address") as mock_reverse:
                mock_reverse.return_value = "reversed_ip"

                result, invalid = ptr_resolve(self.logger, "198.51.100.1")

                self.assertIsNone(result)
                self.assertTrue(invalid)

    def test_495_ptr_resolve_logging_verification(self):
        """Test PTR resolution logging behavior"""
        from acme2certifier.acme_srv.helpers.network import ptr_resolve

        with patch("dns.resolver.Resolver") as mock_resolver_class:
            mock_resolver = Mock()
            mock_resolver_class.return_value = mock_resolver

            # Mock successful PTR resolution
            mock_ptr_answer = [Mock(__str__=Mock(return_value="test.example.org."))]
            mock_resolver.resolve.return_value = mock_ptr_answer

            with patch("dns.reversename.from_address") as mock_reverse:
                mock_reverse.return_value = "reversed_ip"

                with self.assertLogs(self.logger, level="DEBUG") as log_context:
                    result, invalid = ptr_resolve(self.logger, "93.184.216.34")

                self.assertEqual(result, "test.example.org")
                self.assertFalse(invalid)

                # Verify debug logs
                self.assertTrue(
                    any(
                        "Helper.ptr_resolve(93.184.216.34)" in record.message
                        for record in log_context.records
                    )
                )
                self.assertTrue(
                    any(
                        "Helper.ptr_resolve(93.184.216.34) ended with:"
                        in record.message
                        for record in log_context.records
                    )
                )

    def test_496_ptr_resolve_error_logging_verification(self):
        """Test PTR resolution error logging behavior"""
        from acme2certifier.acme_srv.helpers.network import ptr_resolve

        with patch("dns.resolver.Resolver") as mock_resolver_class:
            mock_resolver = Mock()
            mock_resolver_class.return_value = mock_resolver
            mock_resolver.resolve.side_effect = Exception("Connection timeout")

            with patch("dns.reversename.from_address") as mock_reverse:
                mock_reverse.return_value = "reversed_ip"

                with self.assertLogs(self.logger, level="DEBUG") as log_context:
                    result, invalid = ptr_resolve(self.logger, "127.0.0.1")

                self.assertIsNone(result)
                self.assertTrue(invalid)

                # Verify error logging
                self.assertTrue(
                    any(
                        "Error while resolving 127.0.0.1: Connection timeout"
                        in record.message
                        for record in log_context.records
                    )
                )

    def test_497_ptr_resolve_ipv6_address(self):
        """Test PTR resolution with IPv6 address"""
        from acme2certifier.acme_srv.helpers.network import ptr_resolve

        with patch("dns.resolver.Resolver") as mock_resolver_class:
            mock_resolver = Mock()
            mock_resolver_class.return_value = mock_resolver

            # Mock successful PTR resolution for IPv6
            mock_ptr_answer = [Mock(__str__=Mock(return_value="ipv6.example.com."))]
            mock_resolver.resolve.return_value = mock_ptr_answer

            with patch("dns.reversename.from_address") as mock_reverse:
                mock_reverse.return_value = "ipv6_reversed"

                result, invalid = ptr_resolve(self.logger, "2001:db8::1")

                self.assertEqual(result, "ipv6.example.com")
                self.assertFalse(invalid)
                mock_reverse.assert_called_once_with("2001:db8::1")
                mock_resolver.resolve.assert_called_once_with("ipv6_reversed", "PTR")

    def test_498_url_get_with_default_dns_successful_200(self):
        """Test successful HTTP request with 200 status code"""
        from acme2certifier.acme_srv.helpers.network import url_get_with_default_dns

        with patch("acme2certifier.acme_srv.helpers.network.v6_adjust") as mock_v6_adjust:
            mock_v6_adjust.return_value = ({"User-Agent": "test"}, "http://example.com")

            with patch("requests.get") as mock_get:
                mock_response = Mock()
                mock_response.text = "Success response"
                mock_response.status_code = 200
                mock_get.return_value = mock_response

                result, status_code, error_msg = url_get_with_default_dns(
                    self.logger, "http://example.com", {}, True, 30
                )

                self.assertEqual(result, "Success response")
                self.assertEqual(status_code, 200)
                self.assertIsNone(error_msg)
                mock_get.assert_called_once_with(
                    "http://example.com",
                    verify=True,
                    timeout=30,
                    headers={"User-Agent": "test"},
                    proxies={},
                )

    def test_499_url_get_with_default_dns_successful_non_200(self):
        """Test successful HTTP request with non-200 status code"""
        from acme2certifier.acme_srv.helpers.network import url_get_with_default_dns

        with patch("acme2certifier.acme_srv.helpers.network.v6_adjust") as mock_v6_adjust:
            mock_v6_adjust.return_value = ({"User-Agent": "test"}, "http://example.com")

            with patch("requests.get") as mock_get:
                mock_response = Mock()
                mock_response.text = "Not found"
                mock_response.status_code = 404
                mock_response.reason = "Not Found"
                mock_get.return_value = mock_response

                result, status_code, error_msg = url_get_with_default_dns(
                    self.logger, "http://example.com", {}, True, 30
                )

                self.assertEqual(result, "Not found")
                self.assertEqual(status_code, 404)
                self.assertEqual(error_msg, "http://example.com Not Found")

    def test_500_url_get_with_default_dns_exception_fallback_success(self):
        """Test exception in first request triggers IPv4 fallback - success"""
        from acme2certifier.acme_srv.helpers.network import url_get_with_default_dns

        with patch("acme2certifier.acme_srv.helpers.network.v6_adjust") as mock_v6_adjust:
            mock_v6_adjust.return_value = ({"User-Agent": "test"}, "http://example.com")

            with patch("requests.get") as mock_get:
                # First call fails, second call (fallback) succeeds
                mock_response = Mock()
                mock_response.text = "Fallback success"
                mock_response.status_code = 200
                mock_get.side_effect = [
                    Exception("Initial request failed"),
                    mock_response,
                ]

                with patch("acme2certifier.acme_srv.helpers.network.urllib3_cn") as mock_urllib3:
                    old_gai_family = Mock()
                    mock_urllib3.allowed_gai_family = old_gai_family

                    result, status_code, error_msg = url_get_with_default_dns(
                        self.logger,
                        "http://example.com",
                        {"http": "proxy:8080"},
                        True,
                        30,
                    )

                    self.assertEqual(result, "Fallback success")
                    self.assertEqual(status_code, 200)
                    self.assertIsNone(error_msg)
                    # Verify fallback call
                    self.assertEqual(mock_get.call_count, 2)
                    # Verify old GAI family was restored
                    self.assertEqual(mock_urllib3.allowed_gai_family, old_gai_family)

    def test_501_url_get_with_default_dns_fallback_read_timeout(self):
        """Test ReadTimeout exception in IPv4 fallback"""
        from acme2certifier.acme_srv.helpers.network import url_get_with_default_dns

        with patch("acme2certifier.acme_srv.helpers.network.v6_adjust") as mock_v6_adjust:
            mock_v6_adjust.return_value = ({"User-Agent": "test"}, "http://example.com")

            with patch("requests.get") as mock_get:
                mock_get.side_effect = [
                    Exception("Initial request failed"),
                    requests.exceptions.ReadTimeout("Read timeout"),
                ]

                with patch("acme2certifier.acme_srv.helpers.network.urllib3_cn") as mock_urllib3:
                    old_gai_family = Mock()
                    mock_urllib3.allowed_gai_family = old_gai_family

                    result, status_code, error_msg = url_get_with_default_dns(
                        self.logger, "http://example.com", {}, False, 10
                    )

                    self.assertIsNone(result)
                    self.assertEqual(status_code, 500)
                    self.assertEqual(
                        error_msg,
                        "Could not fetch URL: http://example.com - Read timeout.",
                    )
                    # Verify old GAI family was restored
                    self.assertEqual(mock_urllib3.allowed_gai_family, old_gai_family)

    def test_502_url_get_with_default_dns_fallback_connection_error(self):
        """Test ConnectionError exception in IPv4 fallback"""
        from acme2certifier.acme_srv.helpers.network import url_get_with_default_dns

        with patch("acme2certifier.acme_srv.helpers.network.v6_adjust") as mock_v6_adjust:
            mock_v6_adjust.return_value = ({"User-Agent": "test"}, "http://example.com")

            with patch("requests.get") as mock_get:
                mock_get.side_effect = [
                    Exception("Initial request failed"),
                    requests.exceptions.ConnectionError("Connection failed"),
                ]

                with patch("acme2certifier.acme_srv.helpers.network.urllib3_cn") as mock_urllib3:
                    old_gai_family = Mock()
                    mock_urllib3.allowed_gai_family = old_gai_family

                    result, status_code, error_msg = url_get_with_default_dns(
                        self.logger, "http://example.com", {}, True, 20
                    )

                    self.assertIsNone(result)
                    self.assertEqual(status_code, 500)
                    self.assertEqual(
                        error_msg,
                        "Could not fetch URL: http://example.com - Connection error.",
                    )
                    # Verify old GAI family was restored
                    self.assertEqual(mock_urllib3.allowed_gai_family, old_gai_family)

    def test_503_url_get_with_default_dns_fallback_generic_exception(self):
        """Test generic exception in IPv4 fallback"""
        from acme2certifier.acme_srv.helpers.network import url_get_with_default_dns

        with patch("acme2certifier.acme_srv.helpers.network.v6_adjust") as mock_v6_adjust:
            mock_v6_adjust.return_value = ({"User-Agent": "test"}, "http://example.com")

            with patch("requests.get") as mock_get:
                mock_get.side_effect = [
                    Exception("Initial request failed"),
                    RuntimeError("Unexpected error"),
                ]

                with patch("acme2certifier.acme_srv.helpers.network.urllib3_cn") as mock_urllib3:
                    old_gai_family = Mock()
                    mock_urllib3.allowed_gai_family = old_gai_family

                    result, status_code, error_msg = url_get_with_default_dns(
                        self.logger, "http://example.com", {}, True, 15
                    )

                    self.assertIsNone(result)
                    self.assertEqual(status_code, 500)
                    self.assertEqual(
                        error_msg, "Could not fetch URL: http://example.com"
                    )
                    # Verify old GAI family was restored
                    self.assertEqual(mock_urllib3.allowed_gai_family, old_gai_family)

    def test_504_url_get_with_default_dns_fallback_non_200(self):
        """Test non-200 status in IPv4 fallback"""
        from acme2certifier.acme_srv.helpers.network import url_get_with_default_dns

        with patch("acme2certifier.acme_srv.helpers.network.v6_adjust") as mock_v6_adjust:
            mock_v6_adjust.return_value = ({"User-Agent": "test"}, "http://example.com")

            with patch("requests.get") as mock_get:
                mock_response = Mock()
                mock_response.text = "Server Error"
                mock_response.status_code = 500
                mock_response.reason = "Internal Server Error"

                mock_get.side_effect = [
                    Exception("Initial request failed"),
                    mock_response,
                ]

                with patch("acme2certifier.acme_srv.helpers.network.urllib3_cn") as mock_urllib3:
                    old_gai_family = Mock()
                    mock_urllib3.allowed_gai_family = old_gai_family

                    result, status_code, error_msg = url_get_with_default_dns(
                        self.logger, "http://example.com", {}, True, 25
                    )

                    self.assertEqual(result, "Server Error")
                    self.assertEqual(status_code, 500)
                    self.assertEqual(
                        error_msg, "http://example.com Internal Server Error"
                    )
                    # Verify old GAI family was restored
                    self.assertEqual(mock_urllib3.allowed_gai_family, old_gai_family)

    def test_505_url_get_with_default_dns_with_proxy_config(self):
        """Test request with proxy configuration"""
        from acme2certifier.acme_srv.helpers.network import url_get_with_default_dns

        with patch("acme2certifier.acme_srv.helpers.network.v6_adjust") as mock_v6_adjust:
            mock_v6_adjust.return_value = ({"User-Agent": "test"}, "http://example.com")

            with patch("requests.get") as mock_get:
                mock_response = Mock()
                mock_response.text = "Proxy response"
                mock_response.status_code = 200
                mock_get.return_value = mock_response

                proxy_config = {
                    "http": "proxy.example.com:8080",
                    "https": "proxy.example.com:8080",
                }

                result, status_code, error_msg = url_get_with_default_dns(
                    self.logger, "http://example.com", proxy_config, False, 30
                )

                self.assertEqual(result, "Proxy response")
                self.assertEqual(status_code, 200)
                self.assertIsNone(error_msg)
                mock_get.assert_called_once_with(
                    "http://example.com",
                    verify=False,
                    timeout=30,
                    headers={"User-Agent": "test"},
                    proxies=proxy_config,
                )

    def test_506_url_get_with_default_dns_logging_verification(self):
        """Test logging behavior in url_get_with_default_dns"""
        from acme2certifier.acme_srv.helpers.network import url_get_with_default_dns

        with patch("acme2certifier.acme_srv.helpers.network.v6_adjust") as mock_v6_adjust:
            mock_v6_adjust.return_value = ({"User-Agent": "test"}, "http://example.com")

            with patch("requests.get") as mock_get:
                mock_get.side_effect = [
                    Exception("Initial request failed"),
                    requests.exceptions.ReadTimeout("Read timeout"),
                ]

                with patch("acme2certifier.acme_srv.helpers.network.urllib3_cn"):
                    with self.assertLogs(self.logger, level="DEBUG") as log_context:
                        result, status_code, error_msg = url_get_with_default_dns(
                            self.logger, "http://example.com", {}, True, 20
                        )

                    self.assertIsNone(result)
                    self.assertEqual(status_code, 500)

                    # Verify debug logs
                    self.assertTrue(
                        any(
                            "Helper.url_get_with_default_dns(http://example.com) vrf=True, timout:20"
                            in record.message
                            for record in log_context.records
                        )
                    )
                    self.assertTrue(
                        any(
                            "Helper.url_get_with_default_dns(Initial request failed): error"
                            in record.message
                            for record in log_context.records
                        )
                    )
                    self.assertTrue(
                        any(
                            "Helper.url_get_with_default_dns(http://example.com): fallback to v4"
                            in record.message
                            for record in log_context.records
                        )
                    )
                    self.assertTrue(
                        any(
                            "Helper.url_get_with_default_dns(http://example.com): read timeout"
                            in record.message
                            for record in log_context.records
                        )
                    )

    def test_507_allowed_gai_family(self):
        """Test allowed_gai_family function returns IPv4"""
        from acme2certifier.acme_srv.helpers.network import allowed_gai_family
        import socket

        result = allowed_gai_family()

        self.assertEqual(result, socket.AF_INET)

    def test_508_config_allowed_domainlist_load_deprecated_section(self):
        """Test config_allowed_domainlist_load loads from deprecated CAhandler section and logs warning."""
        from acme2certifier.acme_srv.helpers import config

        # Simulate config_dic as a dict, as expected by the function
        cfg = {"CAhandler": {"allowed_domainlist": "example.com,example.org"}}
        with self.assertLogs(self.logger, level="WARNING") as log_context:
            result = config.config_allowed_domainlist_load(self.logger, cfg)
        from acme2certifier.acme_srv.helpers.global_variables import PARSING_ERR_MSG

        self.assertEqual(result, PARSING_ERR_MSG)
        self.assertTrue(any("deprecated" in msg.lower() for msg in log_context.output))

    def test_509_config_allowed_domainlist_load_invalid_json(self):
        """Test config_allowed_domainlist_load handles invalid JSON and logs warning."""
        from acme2certifier.acme_srv.helpers import config

        # Simulate a config dict with invalid JSON in Order section
        cfg = {"Order": {"allowed_domainlist": "not-a-json-list"}}
        with self.assertLogs(self.logger, level="WARNING") as log_context:
            from acme2certifier.acme_srv.helpers.global_variables import PARSING_ERR_MSG

            result = config.config_allowed_domainlist_load(self.logger, cfg)
        self.assertEqual(result, PARSING_ERR_MSG)
        self.assertTrue(
            any(
                "failed to load allowed_domainlist" in msg.lower()
                for msg in log_context.output
            )
        )

    def test_510_pkcs7_to_pem(self):
        """test pkcs7 to pem default output"""
        with open(self.dir_path + "/ca/certs.p7b", "r") as fso:
            file_content = fso.read()
        with open(self.dir_path + "/ca/certs.pem", "r") as fso:
            result = fso.read()
        self.assertEqual(result, self.pkcs7_to_pem(self.logger, file_content))

    def test_511_pkcs7_to_pem(self):
        """test pkcs7 to pem output string"""
        with open(self.dir_path + "/ca/certs.p7b", "r") as fso:
            file_content = fso.read()
        with open(self.dir_path + "/ca/certs.pem", "r") as fso:
            result = fso.read()
        self.assertEqual(result, self.pkcs7_to_pem(self.logger, file_content, "string"))

    def test_512_pkcs7_to_pem(self):
        """test pkcs7 to pem output list"""
        with open(self.dir_path + "/ca/certs.p7b", "r") as fso:
            file_content = fso.read()
        result = [
            "-----BEGIN CERTIFICATE-----\nMIIFTzCCAzegAwIBAgIIAzHyhSyrXfMwDQYJKoZIhvcNAQELBQAwKzEXMBUGA1UE\nCxMOYWNtZTJjZXJ0aWZpZXIxEDAOBgNVBAMTB3Jvb3QtY2EwHhcNMjAwNTI3MTM1\nNDAwWhcNMzAwNTI2MjM1OTAwWjAqMRcwFQYDVQQLEw5hY21lMmNlcnRpZmllcjEP\nMA0GA1UEAxMGc3ViLWNhMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA\nxXHaGZsolXe+PBdUryngHP9VbBC1mehqeTtYI+hqsqGNH7q9a7bSrxMwFuF1kYL8\njqqxkJdtl0L94xcxJg/ZdMx7Nt0vGI+BaAuTpEpUEHeN4tqS6NhB/m/0LGkAELc/\nqkzmoO4B1FDwEEj/3IXtZcupqG80oDt7jWSGXdtF7NTjzcumznMeRXidCdhxRxT/\n/WrsChaytXo0xWZ56oeNwd6x6Dr8/39PBOWtj4fldyDcg+Q+alci2tx9pxmu2bCV\nXcB9ftCLKhDk2WEHE88bgKSp7fV2RCmq9po+Tx8JJ7qecLunUsK/F0XN4kpoQLm9\nhcymqchnMSncSiyin1dQHGHWgXDtBDdq6A2Z6rx26Qk5H9HTYvcNSe1YwFEDoGLB\nZQjbCPWiaqoaH4agBQTclPvrrSCRaVmhUSO+pBtSXDkmN4t3MDZxfgRkp8ixwkB1\n5Y5f0LTpCyAJsdQDw8+Ea0aDqO30eskh4CErnm9+Fejd9Ew2cwpdwfBXzVSbYilM\nGueQihZHvJmVRxAwU69aO2Qs8B0tQ60CfWKVlmWPiakrvYYlPp0FBsM61G6LZEN8\nhH2CKnS8hHv5IWEXZvp0Pk8V3P5h6bWN0Tl+x/V1Prt7Wp8NoiPETE8XyDDxe6dm\nKxztWBH/mTsJyMGb6ZiUoXdPU9TFUKqHxTRLHaxfsPsCAwEAAaN4MHYwEgYDVR0T\nAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUv96OjgYiIqutQ8jd1E+oq0hBPtUwDgYD\nVR0PAQH/BAQDAgGGMBEGCWCGSAGG+EIBAQQEAwIABzAeBglghkgBhvhCAQ0EERYP\neGNhIGNlcnRpZmljYXRlMA0GCSqGSIb3DQEBCwUAA4ICAQBbHLEVyg4f9uEujroc\n31UVyDRLMdPgEPLjOenSBCBmH0N81whDmxNI/7JAAB6J14WMX8OLF0HkZnb7G77W\nvDhy1aFvQFbXHBz3/zUO9Mw9J4L2XEW6ond3Nsh1m2oXeBde3R3ANxuIzHqZDlP9\n6YrRcHjnf4+1/5AKDJAvJD+gFb5YnYUKH2iSvHUvG17xcZx98Rf2eo8LealG4JqH\nJh4sKRy0VjDQD7jXSCbweTHEb8wz+6OfNGrIo+BhTFP5vPcwE4nlJwYBoaOJ5cVa\n7gdQJ7WkLSxvwHxuxzvSVK73u3jl3I9SqTrbMLG/jeJyV0P8EvdljOaGnCtQVRwC\nzM4ptXUvKhKOHy7/nyTF/Bc35ZwwL/2xWvNK1+NibgE/6CFxupwWpdmxQbVVuoQ3\n2tUil9ty0yC6m5GKE8+t1lrZuxyA+b/TBnYNO5xo8UEMbkpxaNYSwmw+f/loxXP/\nM7sIBcLvy2ugHEBxwd9o/kLXeXT2DaRvxPjp4yk8MpJRpNmz3aB5HJwaUnaRLVo5\nZ3XWWXmjMGZ6/m0AAoDbDz/pXtOoJZT8BJdD1DuDdszVsQnLVn4B/LtIXL6FbXsF\nzfv6ERP9a5gpKUZ+4NjgrnlGtdccNZpwyWF0IXcvaq3b8hXIRO4hMjzHeHfzJN4t\njX1vlY35Ofonc4+6dRVamBiF9A==\n-----END CERTIFICATE-----\n",
            "-----BEGIN CERTIFICATE-----\nMIIFcDCCA1igAwIBAgIIevLTTxOMoZgwDQYJKoZIhvcNAQELBQAwKzEXMBUGA1UE\nCxMOYWNtZTJjZXJ0aWZpZXIxEDAOBgNVBAMTB3Jvb3QtY2EwHhcNMjAwNTI3MDAw\nMDAwWhcNMzAwNTI2MjM1OTU5WjArMRcwFQYDVQQLEw5hY21lMmNlcnRpZmllcjEQ\nMA4GA1UEAxMHcm9vdC1jYTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB\nAJy4UZHdZgYt64k/rFamoC676tYvtabeuiqVw1c6oVZI897cFLG6BYwyr2Eaj7tF\nrqTJDeMN4vZSudLsmLDq6m8KwX/riPzUTIlcjM5aIMANZr9rLEs3NWtcivolB5aQ\n1slhdVitUPLuxsFnYeQTyxFyP7lng9M/Z403KLG8phdmKjM0vJkaj4OuKOXf3UsW\nqWQYyRl/ms07xVj02uq08LkoeO+jtQisvyVXURdaCceZtyK/ZBQ7NFCsbK112cVR\n1e2aJol7NJAA6Wm6iBzAdkAA2l3kh40SLoEbaiaVMixLN2vilIZOOAoDXX4+T6ir\n+KnDVSJ2yu5c/OJMwuXwHrh7Lgg1vsFR5TNehknhjUuWOUO+0TkKPg2A7KTg72OZ\n2mOcLZIbxzr1P5RRvdmLQLPrTF2EJvpQPNmbXqN3ZVWEvfHTjkkTFY/dsOTvFTgS\nri15zYKch8votcU7z+BQhgmMtwO2JhPMmZ6ABd9skI7ijWpwOltAhxtdoBO6T6CB\nCrE2yXc6V/PyyAKcFglNmIght5oXsnE+ub/dtx8f9Iea/xNPdo5aGy8fdaitolDK\n16kd3Kb7OE4HMHIwOxxF1BEAqerxxhbLMRBr8hRSZI5cvLzWLvpAQ5zuhjD6V3b9\nBYFd4ujAu3zl3mbzdbYjFoGOX6aBZaGDxlc4O2W7HxntAgMBAAGjgZcwgZQwDwYD\nVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUDGVvuTFYZtEAkz3af9wRKDDvAswwHwYD\nVR0jBBgwFoAUDGVvuTFYZtEAkz3af9wRKDDvAswwDgYDVR0PAQH/BAQDAgGGMBEG\nCWCGSAGG+EIBAQQEAwIABzAeBglghkgBhvhCAQ0EERYPeGNhIGNlcnRpZmljYXRl\nMA0GCSqGSIb3DQEBCwUAA4ICAQAjko7dX+iCgT+m3Iy1Vg6j7MRevPAzq1lqHRRN\nNdt2ct530pIut7Fv5V2xYk35ka+i/G+XyOvTXa9vAUKiBtiRnUPsXu4UcS7CcrCX\nEzHx4eOtHnp5wDhO0Fx5/OUZTaP+L7Pd1GD/j953ibx5bMa/M9Rj+S486nst57tu\nDRmEAavFDiMd6L3jH4YSckjmIH2uSeDIaRa9k6ag077XmWhvVYQ9tuR7RGbSuuV3\nFc6pqcFbbWpoLhNRcFc+hbUKOsKl2cP+QEKP/H2s3WMllqgAKKZeO+1KOsGo1CDs\n475bIXyCBpFbH2HOPatmu3yZRQ9fj9ta9EW46n33DFRNLinFWa4WJs4yLVP1juge\n2TCOyA1t61iy++RRXSG3e7NFYrEZuCht1EdDAdzIUY89m9NCPwoDYS4CahgnfkkO\n7YQe6f6yqK6isyf8ZFcp1uF58eERDiF/FDqS8nLmCdURuI56DDoNvDpig5J/9RNW\nG8vEvt2p7QrjeZ3EAatx5JuYty/NKTHZwJWk51CgzEgzDwzE2JIiqeldtL5d0Sl6\neVuv0G04BEyuXxEWpgVVzBS4qEFIBSnTJzgu1PXmId3yLvg2Nr8NKvwyZmN5xKFp\n0A9BWo15zW1PXDaD+l39oTYD7agjXkzTAjYIcfNJ7ATIYFD0xAvNAOf70s7aNupF\nfvkG2Q==\n-----END CERTIFICATE-----\n",
        ]
        self.assertEqual(result, self.pkcs7_to_pem(self.logger, file_content, "list"))

    def test_513_pkcs7_to_pem(self):
        """test pkcs7 to pem output list"""
        with open(self.dir_path + "/ca/certs.p7b", "r") as fso:
            file_content = fso.read()
        result = None
        self.assertEqual(
            result, self.pkcs7_to_pem(self.logger, file_content, "unknown")
        )

    def test_514_pkcs7_to_pem(self):
        """test pkcs7 to pem output list"""

        file_content = base64.b64decode(
            "MIIK9AYJKoZIhvcNAQcCoIIK5TCCCuECAQExADALBgkqhkiG9w0BBwGgggrHMIIFTzCCAzegAwIBAgIIAzHyhSyrXfMwDQYJKoZIhvcNAQELBQAwKzEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxEDAOBgNVBAMTB3Jvb3QtY2EwHhcNMjAwNTI3MTM1NDAwWhcNMzAwNTI2MjM1OTAwWjAqMRcwFQYDVQQLEw5hY21lMmNlcnRpZmllcjEPMA0GA1UEAxMGc3ViLWNhMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxXHaGZsolXe+PBdUryngHP9VbBC1mehqeTtYI+hqsqGNH7q9a7bSrxMwFuF1kYL8jqqxkJdtl0L94xcxJg/ZdMx7Nt0vGI+BaAuTpEpUEHeN4tqS6NhB/m/0LGkAELc/qkzmoO4B1FDwEEj/3IXtZcupqG80oDt7jWSGXdtF7NTjzcumznMeRXidCdhxRxT//WrsChaytXo0xWZ56oeNwd6x6Dr8/39PBOWtj4fldyDcg+Q+alci2tx9pxmu2bCVXcB9ftCLKhDk2WEHE88bgKSp7fV2RCmq9po+Tx8JJ7qecLunUsK/F0XN4kpoQLm9hcymqchnMSncSiyin1dQHGHWgXDtBDdq6A2Z6rx26Qk5H9HTYvcNSe1YwFEDoGLBZQjbCPWiaqoaH4agBQTclPvrrSCRaVmhUSO+pBtSXDkmN4t3MDZxfgRkp8ixwkB15Y5f0LTpCyAJsdQDw8+Ea0aDqO30eskh4CErnm9+Fejd9Ew2cwpdwfBXzVSbYilMGueQihZHvJmVRxAwU69aO2Qs8B0tQ60CfWKVlmWPiakrvYYlPp0FBsM61G6LZEN8hH2CKnS8hHv5IWEXZvp0Pk8V3P5h6bWN0Tl+x/V1Prt7Wp8NoiPETE8XyDDxe6dmKxztWBH/mTsJyMGb6ZiUoXdPU9TFUKqHxTRLHaxfsPsCAwEAAaN4MHYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUv96OjgYiIqutQ8jd1E+oq0hBPtUwDgYDVR0PAQH/BAQDAgGGMBEGCWCGSAGG+EIBAQQEAwIABzAeBglghkgBhvhCAQ0EERYPeGNhIGNlcnRpZmljYXRlMA0GCSqGSIb3DQEBCwUAA4ICAQBbHLEVyg4f9uEujroc31UVyDRLMdPgEPLjOenSBCBmH0N81whDmxNI/7JAAB6J14WMX8OLF0HkZnb7G77WvDhy1aFvQFbXHBz3/zUO9Mw9J4L2XEW6ond3Nsh1m2oXeBde3R3ANxuIzHqZDlP96YrRcHjnf4+1/5AKDJAvJD+gFb5YnYUKH2iSvHUvG17xcZx98Rf2eo8LealG4JqHJh4sKRy0VjDQD7jXSCbweTHEb8wz+6OfNGrIo+BhTFP5vPcwE4nlJwYBoaOJ5cVa7gdQJ7WkLSxvwHxuxzvSVK73u3jl3I9SqTrbMLG/jeJyV0P8EvdljOaGnCtQVRwCzM4ptXUvKhKOHy7/nyTF/Bc35ZwwL/2xWvNK1+NibgE/6CFxupwWpdmxQbVVuoQ32tUil9ty0yC6m5GKE8+t1lrZuxyA+b/TBnYNO5xo8UEMbkpxaNYSwmw+f/loxXP/M7sIBcLvy2ugHEBxwd9o/kLXeXT2DaRvxPjp4yk8MpJRpNmz3aB5HJwaUnaRLVo5Z3XWWXmjMGZ6/m0AAoDbDz/pXtOoJZT8BJdD1DuDdszVsQnLVn4B/LtIXL6FbXsFzfv6ERP9a5gpKUZ+4NjgrnlGtdccNZpwyWF0IXcvaq3b8hXIRO4hMjzHeHfzJN4tjX1vlY35Ofonc4+6dRVamBiF9DCCBXAwggNYoAMCAQICCHry008TjKGYMA0GCSqGSIb3DQEBCwUAMCsxFzAVBgNVBAsTDmFjbWUyY2VydGlmaWVyMRAwDgYDVQQDEwdyb290LWNhMB4XDTIwMDUyNzAwMDAwMFoXDTMwMDUyNjIzNTk1OVowKzEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxEDAOBgNVBAMTB3Jvb3QtY2EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCcuFGR3WYGLeuJP6xWpqAuu+rWL7Wm3roqlcNXOqFWSPPe3BSxugWMMq9hGo+7Ra6kyQ3jDeL2UrnS7Jiw6upvCsF/64j81EyJXIzOWiDADWa/ayxLNzVrXIr6JQeWkNbJYXVYrVDy7sbBZ2HkE8sRcj+5Z4PTP2eNNyixvKYXZiozNLyZGo+Drijl391LFqlkGMkZf5rNO8VY9NrqtPC5KHjvo7UIrL8lV1EXWgnHmbciv2QUOzRQrGytddnFUdXtmiaJezSQAOlpuogcwHZAANpd5IeNEi6BG2omlTIsSzdr4pSGTjgKA11+Pk+oq/ipw1UidsruXPziTMLl8B64ey4INb7BUeUzXoZJ4Y1LljlDvtE5Cj4NgOyk4O9jmdpjnC2SG8c69T+UUb3Zi0Cz60xdhCb6UDzZm16jd2VVhL3x045JExWP3bDk7xU4Eq4tec2CnIfL6LXFO8/gUIYJjLcDtiYTzJmegAXfbJCO4o1qcDpbQIcbXaATuk+ggQqxNsl3Olfz8sgCnBYJTZiIIbeaF7JxPrm/3bcfH/SHmv8TT3aOWhsvH3WoraJQytepHdym+zhOBzByMDscRdQRAKnq8cYWyzEQa/IUUmSOXLy81i76QEOc7oYw+ld2/QWBXeLowLt85d5m83W2IxaBjl+mgWWhg8ZXODtlux8Z7QIDAQABo4GXMIGUMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAxlb7kxWGbRAJM92n/cESgw7wLMMB8GA1UdIwQYMBaAFAxlb7kxWGbRAJM92n/cESgw7wLMMA4GA1UdDwEB/wQEAwIBhjARBglghkgBhvhCAQEEBAMCAAcwHgYJYIZIAYb4QgENBBEWD3hjYSBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAgEAI5KO3V/ogoE/ptyMtVYOo+zEXrzwM6tZah0UTTXbdnLed9KSLrexb+VdsWJN+ZGvovxvl8jr012vbwFCogbYkZ1D7F7uFHEuwnKwlxMx8eHjrR56ecA4TtBcefzlGU2j/i+z3dRg/4/ed4m8eWzGvzPUY/kuPOp7Lee7bg0ZhAGrxQ4jHei94x+GEnJI5iB9rkngyGkWvZOmoNO+15lob1WEPbbke0Rm0rrldxXOqanBW21qaC4TUXBXPoW1CjrCpdnD/kBCj/x9rN1jJZaoACimXjvtSjrBqNQg7OO+WyF8ggaRWx9hzj2rZrt8mUUPX4/bWvRFuOp99wxUTS4pxVmuFibOMi1T9Y7oHtkwjsgNbetYsvvkUV0ht3uzRWKxGbgobdRHQwHcyFGPPZvTQj8KA2EuAmoYJ35JDu2EHun+sqiuorMn/GRXKdbhefHhEQ4hfxQ6kvJy5gnVEbiOegw6Dbw6YoOSf/UTVhvLxL7dqe0K43mdxAGrceSbmLcvzSkx2cCVpOdQoMxIMw8MxNiSIqnpXbS+XdEpenlbr9BtOARMrl8RFqYFVcwUuKhBSAUp0yc4LtT15iHd8i74Nja/DSr8MmZjecShadAPQVqNec1tT1w2g/pd/aE2A+2oI15M0wI2CHHzSewEyGBQ9MQLzQDn+9LO2jbqRX75BtmhADEA"
        )
        result = [
            "-----BEGIN CERTIFICATE-----\nMIIFTzCCAzegAwIBAgIIAzHyhSyrXfMwDQYJKoZIhvcNAQELBQAwKzEXMBUGA1UE\nCxMOYWNtZTJjZXJ0aWZpZXIxEDAOBgNVBAMTB3Jvb3QtY2EwHhcNMjAwNTI3MTM1\nNDAwWhcNMzAwNTI2MjM1OTAwWjAqMRcwFQYDVQQLEw5hY21lMmNlcnRpZmllcjEP\nMA0GA1UEAxMGc3ViLWNhMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA\nxXHaGZsolXe+PBdUryngHP9VbBC1mehqeTtYI+hqsqGNH7q9a7bSrxMwFuF1kYL8\njqqxkJdtl0L94xcxJg/ZdMx7Nt0vGI+BaAuTpEpUEHeN4tqS6NhB/m/0LGkAELc/\nqkzmoO4B1FDwEEj/3IXtZcupqG80oDt7jWSGXdtF7NTjzcumznMeRXidCdhxRxT/\n/WrsChaytXo0xWZ56oeNwd6x6Dr8/39PBOWtj4fldyDcg+Q+alci2tx9pxmu2bCV\nXcB9ftCLKhDk2WEHE88bgKSp7fV2RCmq9po+Tx8JJ7qecLunUsK/F0XN4kpoQLm9\nhcymqchnMSncSiyin1dQHGHWgXDtBDdq6A2Z6rx26Qk5H9HTYvcNSe1YwFEDoGLB\nZQjbCPWiaqoaH4agBQTclPvrrSCRaVmhUSO+pBtSXDkmN4t3MDZxfgRkp8ixwkB1\n5Y5f0LTpCyAJsdQDw8+Ea0aDqO30eskh4CErnm9+Fejd9Ew2cwpdwfBXzVSbYilM\nGueQihZHvJmVRxAwU69aO2Qs8B0tQ60CfWKVlmWPiakrvYYlPp0FBsM61G6LZEN8\nhH2CKnS8hHv5IWEXZvp0Pk8V3P5h6bWN0Tl+x/V1Prt7Wp8NoiPETE8XyDDxe6dm\nKxztWBH/mTsJyMGb6ZiUoXdPU9TFUKqHxTRLHaxfsPsCAwEAAaN4MHYwEgYDVR0T\nAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUv96OjgYiIqutQ8jd1E+oq0hBPtUwDgYD\nVR0PAQH/BAQDAgGGMBEGCWCGSAGG+EIBAQQEAwIABzAeBglghkgBhvhCAQ0EERYP\neGNhIGNlcnRpZmljYXRlMA0GCSqGSIb3DQEBCwUAA4ICAQBbHLEVyg4f9uEujroc\n31UVyDRLMdPgEPLjOenSBCBmH0N81whDmxNI/7JAAB6J14WMX8OLF0HkZnb7G77W\nvDhy1aFvQFbXHBz3/zUO9Mw9J4L2XEW6ond3Nsh1m2oXeBde3R3ANxuIzHqZDlP9\n6YrRcHjnf4+1/5AKDJAvJD+gFb5YnYUKH2iSvHUvG17xcZx98Rf2eo8LealG4JqH\nJh4sKRy0VjDQD7jXSCbweTHEb8wz+6OfNGrIo+BhTFP5vPcwE4nlJwYBoaOJ5cVa\n7gdQJ7WkLSxvwHxuxzvSVK73u3jl3I9SqTrbMLG/jeJyV0P8EvdljOaGnCtQVRwC\nzM4ptXUvKhKOHy7/nyTF/Bc35ZwwL/2xWvNK1+NibgE/6CFxupwWpdmxQbVVuoQ3\n2tUil9ty0yC6m5GKE8+t1lrZuxyA+b/TBnYNO5xo8UEMbkpxaNYSwmw+f/loxXP/\nM7sIBcLvy2ugHEBxwd9o/kLXeXT2DaRvxPjp4yk8MpJRpNmz3aB5HJwaUnaRLVo5\nZ3XWWXmjMGZ6/m0AAoDbDz/pXtOoJZT8BJdD1DuDdszVsQnLVn4B/LtIXL6FbXsF\nzfv6ERP9a5gpKUZ+4NjgrnlGtdccNZpwyWF0IXcvaq3b8hXIRO4hMjzHeHfzJN4t\njX1vlY35Ofonc4+6dRVamBiF9A==\n-----END CERTIFICATE-----\n",
            "-----BEGIN CERTIFICATE-----\nMIIFcDCCA1igAwIBAgIIevLTTxOMoZgwDQYJKoZIhvcNAQELBQAwKzEXMBUGA1UE\nCxMOYWNtZTJjZXJ0aWZpZXIxEDAOBgNVBAMTB3Jvb3QtY2EwHhcNMjAwNTI3MDAw\nMDAwWhcNMzAwNTI2MjM1OTU5WjArMRcwFQYDVQQLEw5hY21lMmNlcnRpZmllcjEQ\nMA4GA1UEAxMHcm9vdC1jYTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB\nAJy4UZHdZgYt64k/rFamoC676tYvtabeuiqVw1c6oVZI897cFLG6BYwyr2Eaj7tF\nrqTJDeMN4vZSudLsmLDq6m8KwX/riPzUTIlcjM5aIMANZr9rLEs3NWtcivolB5aQ\n1slhdVitUPLuxsFnYeQTyxFyP7lng9M/Z403KLG8phdmKjM0vJkaj4OuKOXf3UsW\nqWQYyRl/ms07xVj02uq08LkoeO+jtQisvyVXURdaCceZtyK/ZBQ7NFCsbK112cVR\n1e2aJol7NJAA6Wm6iBzAdkAA2l3kh40SLoEbaiaVMixLN2vilIZOOAoDXX4+T6ir\n+KnDVSJ2yu5c/OJMwuXwHrh7Lgg1vsFR5TNehknhjUuWOUO+0TkKPg2A7KTg72OZ\n2mOcLZIbxzr1P5RRvdmLQLPrTF2EJvpQPNmbXqN3ZVWEvfHTjkkTFY/dsOTvFTgS\nri15zYKch8votcU7z+BQhgmMtwO2JhPMmZ6ABd9skI7ijWpwOltAhxtdoBO6T6CB\nCrE2yXc6V/PyyAKcFglNmIght5oXsnE+ub/dtx8f9Iea/xNPdo5aGy8fdaitolDK\n16kd3Kb7OE4HMHIwOxxF1BEAqerxxhbLMRBr8hRSZI5cvLzWLvpAQ5zuhjD6V3b9\nBYFd4ujAu3zl3mbzdbYjFoGOX6aBZaGDxlc4O2W7HxntAgMBAAGjgZcwgZQwDwYD\nVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUDGVvuTFYZtEAkz3af9wRKDDvAswwHwYD\nVR0jBBgwFoAUDGVvuTFYZtEAkz3af9wRKDDvAswwDgYDVR0PAQH/BAQDAgGGMBEG\nCWCGSAGG+EIBAQQEAwIABzAeBglghkgBhvhCAQ0EERYPeGNhIGNlcnRpZmljYXRl\nMA0GCSqGSIb3DQEBCwUAA4ICAQAjko7dX+iCgT+m3Iy1Vg6j7MRevPAzq1lqHRRN\nNdt2ct530pIut7Fv5V2xYk35ka+i/G+XyOvTXa9vAUKiBtiRnUPsXu4UcS7CcrCX\nEzHx4eOtHnp5wDhO0Fx5/OUZTaP+L7Pd1GD/j953ibx5bMa/M9Rj+S486nst57tu\nDRmEAavFDiMd6L3jH4YSckjmIH2uSeDIaRa9k6ag077XmWhvVYQ9tuR7RGbSuuV3\nFc6pqcFbbWpoLhNRcFc+hbUKOsKl2cP+QEKP/H2s3WMllqgAKKZeO+1KOsGo1CDs\n475bIXyCBpFbH2HOPatmu3yZRQ9fj9ta9EW46n33DFRNLinFWa4WJs4yLVP1juge\n2TCOyA1t61iy++RRXSG3e7NFYrEZuCht1EdDAdzIUY89m9NCPwoDYS4CahgnfkkO\n7YQe6f6yqK6isyf8ZFcp1uF58eERDiF/FDqS8nLmCdURuI56DDoNvDpig5J/9RNW\nG8vEvt2p7QrjeZ3EAatx5JuYty/NKTHZwJWk51CgzEgzDwzE2JIiqeldtL5d0Sl6\neVuv0G04BEyuXxEWpgVVzBS4qEFIBSnTJzgu1PXmId3yLvg2Nr8NKvwyZmN5xKFp\n0A9BWo15zW1PXDaD+l39oTYD7agjXkzTAjYIcfNJ7ATIYFD0xAvNAOf70s7aNupF\nfvkG2Q==\n-----END CERTIFICATE-----\n",
        ]
        self.assertEqual(result, self.pkcs7_to_pem(self.logger, file_content, "list"))

    def test_515_pkcs7_to_pem_tag_replacement_logs_error(self):
        """Test pkcs7_to_pem logs error on tag replacement strategy (line 426)"""
        from acme2certifier.acme_srv.helpers.certificates import pkcs7_to_pem

        logger = Mock()
        # First strategy fails, second succeeds (tag replacement)
        with patch(
            "acme2certifier.acme_srv.helpers.certificates.load_pem_pkcs7_certificates",
            side_effect=[Exception("fail1"), [Mock()]],
        ):
            with patch(
                "acme2certifier.acme_srv.helpers.certificates.convert_string_to_byte",
                side_effect=lambda x: x,
            ):
                result = pkcs7_to_pem(logger, "dummy", outform="list")
        # Should log error for tag replacement
        logger.error.assert_any_call(
            "PKCS7-TAG not found, updated content successfully"
        )
        self.assertIsInstance(result, list)

    def test_516_pkcs7_to_pem_all_strategies_fail(self):
        """Test pkcs7_to_pem logs error and raises if all strategies fail (lines 436-437)"""
        from acme2certifier.acme_srv.helpers.certificates import pkcs7_to_pem

        logger = Mock()
        # All strategies fail
        with (
            patch(
                "acme2certifier.acme_srv.helpers.certificates.load_pem_pkcs7_certificates",
                side_effect=Exception("fail1"),
            ),
            patch(
                "acme2certifier.acme_srv.helpers.certificates.convert_string_to_byte",
                side_effect=lambda x: x,
            ),
            patch(
                "acme2certifier.acme_srv.helpers.certificates.load_der_pkcs7_certificates",
                side_effect=Exception("fail2"),
            ),
        ):
            with self.assertRaises(Exception) as cm:
                pkcs7_to_pem(logger, "dummy", outform="list")
        logger.error.assert_any_call(
            "All PKCS7 loading strategies failed. Last error: %s", cm.exception
        )

    def test_517_config_dryrun_load_not_set(self):
        """Test config_dryrun_load with valid 'true' value."""

    def test_518_config_dryrun_load_not_set(self):
        """Test config_dryrun_load when dryrun is not set."""
        config_dic = configparser.ConfigParser()
        config_dic["DEFAULT"] = {"foo": "bar"}
        self.assertEqual(
            (False, None), self.config_dryrun_load(self.logger, config_dic)
        )

    def test_519_config_dryrun_load_true(self):
        """Test config_dryrun_load with valid 'true' value."""
        config_dic = configparser.ConfigParser()
        config_dic["DEFAULT"] = {"dryrun": "True"}
        true_list = ["true", "True", "TRUE"]
        for val in true_list:
            config_dic["DEFAULT"]["dryrun"] = val
            self.assertEqual(
                (True, None), self.config_dryrun_load(self.logger, config_dic)
            )

    def test_520_config_dryrun_load_false(self):
        """Test config_dryrun_load with valid 'false' value."""
        config_dic = configparser.ConfigParser()
        config_dic["DEFAULT"] = {"dryrun": "False"}
        false_list = ["false", "False", "FALSE"]
        for val in false_list:
            config_dic["DEFAULT"]["dryrun"] = val
            self.assertEqual(
                (False, None), self.config_dryrun_load(self.logger, config_dic)
            )

    def test_521_config_dryrun_load_profile(self):
        """Test config_dryrun_load with invalid value."""
        config_dic = configparser.ConfigParser()
        profile_list = ["profile", "Profile", "PROFILE"]
        for val in profile_list:
            config_dic["DEFAULT"]["dryrun"] = val
            config_dic["DEFAULT"]["dryrun_profile"] = "custom_dryrun_profile"
            self.assertEqual(
                (False, "custom_dryrun_profile"),
                self.config_dryrun_load(self.logger, config_dic),
            )

    def test_522_config_dryrun_load_profile_no_profilename(self):
        """Test config_dryrun_load with invalid value and no dryrun_profile set."""
        config_dic = configparser.ConfigParser()
        config_dic["DEFAULT"]["dryrun"] = "profile"
        with self.assertLogs(self.logger, level="WARNING") as lcm:
            self.assertEqual(
                (False, None), self.config_dryrun_load(self.logger, config_dic)
            )
            self.assertIn(
                "WARNING:test_a2c:Dryrun profile name not set in configuration, please set dryrun_profile parameter",
                lcm.output[0],
            )

    def test_523_is_ip_whitelisted_empty(self):
        """Test is_ip_whitelisted with empty IP list."""
        self.assertFalse(self.is_ip_whitelisted(self.logger, "1.2.3.4", []))

    def test_524_is_ip_whitelisted_noip(self):
        """Test is_ip_whitelisted with no IP provided."""
        self.assertFalse(
            self.is_ip_whitelisted(
                self.logger, "", ["10.0.0.1/8", "172.16.0.1/32", "192.168.123.1"]
            )
        )

    def test_525_is_ip_whitelisted_invalid(self):
        """Test is_ip_whitelisted with invalid IP list."""
        self.assertFalse(
            self.is_ip_whitelisted(
                self.logger,
                "10.0.aa.0",
                ["10.0.0.1/8", "172.16.0.1/32", "192.168.123.1"],
            )
        )

    def test_526_is_ip_whitelisted_invalid(self):
        """Test is_ip_whitelisted with invalid IP list."""
        self.assertFalse(
            self.is_ip_whitelisted(
                self.logger,
                "10.0.0.300",
                ["10.0.0.1/8", "172.16.0.1/32", "192.168.123.1"],
            )
        )

    def test_527_is_ip_whitelisted_no_match(self):
        """Test is_ip_whitelisted with no matching IP."""
        self.assertFalse(
            self.is_ip_whitelisted(
                self.logger,
                "10.1.0.1",
                ["10.0.0.1/16", "172.16.0.1/32", "192.168.123.1"],
            )
        )

    def test_528_is_ip_whitelisted_exact_match(self):
        """Test is_ip_whitelisted with exact matching IP."""
        self.assertTrue(
            self.is_ip_whitelisted(
                self.logger,
                "192.168.123.1",
                ["10.0.0.1/8", "172.16.0.1/32", "192.168.123.1"],
            )
        )

    def test_529_is_ip_whitelisted_cidr_match(self):
        """Test is_ip_whitelisted with CIDR matching IP."""
        self.assertTrue(
            self.is_ip_whitelisted(
                self.logger,
                "10.0.20.1",
                ["10.0.0.1/8", "172.16.0.1/32", "192.168.123.1"],
            )
        )

    def test_530_is_ip_whitelisted_cidr_32match(self):
        """Test is_ip_whitelisted with CIDR /32 matching IP."""
        self.assertTrue(
            self.is_ip_whitelisted(
                self.logger,
                "172.16.0.1",
                ["10.0.0.1/8", "172.16.0.1/32", "192.168.123.1"],
            )
        )

    def test_531_is_ip_whitelisted_invalid_network(self):
        """Test is_ip_whitelisted with invalid network."""
        with self.assertLogs(self.logger, level="ERROR") as lcm:
            self.assertTrue(
                self.is_ip_whitelisted(
                    self.logger,
                    "172.16.0.1",
                    ["10.300.0.0/8", "172.16.0.1/32", "192.168.123.1"],
                )
            )
        self.assertIn(
            "ERROR:test_a2c:Invalid network entry in allowed_iplist: 10.300.0.0/8",
            lcm.output[0],
        )

    def test_532_config_allowed_iplist_load(self):
        """test config_allowed_iplist_load()"""
        config_dic = {"Order": {"allowed_iplist": '["foo", "bar", "foobar"]'}}
        self.assertEqual(
            ["foo", "bar", "foobar"],
            self.config_allowed_iplist_load(self.logger, config_dic),
        )

    def test_533_config_allowed_iplist_load(self):
        """test config_allowed_iplist_load()"""
        config_dic = {"Order": {"allowed_iplist": '["foo"]'}}
        self.assertEqual(
            ["foo"], self.config_allowed_iplist_load(self.logger, config_dic)
        )

    def test_534_config_allowed_iplist_load(self):
        """test config_allowed_iplist_load()"""
        config_dic = {"Order": {"allowed_iplist": "foo"}}
        with self.assertLogs("test_a2c", level="INFO") as lcm:
            self.assertEqual(
                "failed to parse",
                self.config_allowed_iplist_load(self.logger, config_dic),
            )
        self.assertIn(
            "WARNING:test_a2c:Failed to load allowed_iplist from configuration: Expecting value: line 1 column 1 (char 0)",
            lcm.output,
        )

    def test_535_is_email_whitelisted_exact_match(self):
        """Test is_email_whitelisted with exact match"""
        from acme2certifier.acme_srv.helpers.domain_utils import is_email_whitelisted

        email_list = ["user@example.com", "admin@domain.com"]
        self.assertTrue(
            is_email_whitelisted(self.logger, "user@example.com", email_list)
        )
        self.assertTrue(
            is_email_whitelisted(self.logger, "admin@domain.com", email_list)
        )

    def test_536_is_email_whitelisted_case_insensitive(self):
        """Test is_email_whitelisted is case-insensitive"""
        from acme2certifier.acme_srv.helpers.domain_utils import is_email_whitelisted

        email_list = ["User@Example.com", "Admin@Domain.com"]
        self.assertTrue(
            is_email_whitelisted(self.logger, "user@example.com", email_list)
        )
        self.assertTrue(
            is_email_whitelisted(self.logger, "ADMIN@DOMAIN.COM", email_list)
        )

    def test_537_is_email_whitelisted_not_in_list(self):
        """Test is_email_whitelisted returns False for non-matching email"""
        from acme2certifier.acme_srv.helpers.domain_utils import is_email_whitelisted

        email_list = ["user@example.com", "admin@domain.com"]

    def test_538_is_email_whitelisted_with_whitespace(self):
        """Test is_email_whitelisted trims whitespace"""
        from acme2certifier.acme_srv.helpers.domain_utils import is_email_whitelisted

        email_list = [" user@example.com ", "admin@domain.com "]
        self.assertTrue(
            is_email_whitelisted(self.logger, "user@example.com", email_list)
        )
        self.assertTrue(
            is_email_whitelisted(self.logger, "admin@domain.com", email_list)
        )

    def test_539_email_whitelisted_empty_list(self):
        """Test is_email_whitelisted with empty list returns False"""
        from acme2certifier.acme_srv.helpers.domain_utils import is_email_whitelisted

        email_list = []
        self.assertFalse(
            is_email_whitelisted(self.logger, "user@example.com", email_list)
        )

    def test_540_is_email_whitelisted_exact_match(self):
        """Test is_email_whitelisted returns True for exact match."""
        from acme2certifier.acme_srv.helpers.domain_utils import is_email_whitelisted

        email_list = ["user@example.com", "admin@foo.com"]
        self.assertTrue(
            is_email_whitelisted(self.logger, "user@example.com", email_list)
        )
        self.assertTrue(is_email_whitelisted(self.logger, "admin@foo.com", email_list))
        self.assertFalse(
            is_email_whitelisted(self.logger, "other@example.com", email_list)
        )

    def test_541_is_email_whitelisted_wildcard(self):
        """Test is_email_whitelisted returns True for wildcard *@example.com."""
        from acme2certifier.acme_srv.helpers.domain_utils import is_email_whitelisted

        email_list = ["*@example.com"]
        self.assertTrue(
            is_email_whitelisted(self.logger, "user@example.com", email_list)
        )
        self.assertTrue(
            is_email_whitelisted(self.logger, "admin@example.com", email_list)
        )
        self.assertFalse(
            is_email_whitelisted(self.logger, "user@other.com", email_list)
        )

    def test_542_is_email_whitelisted_mixed_patterns(self):
        """Test is_email_whitelisted with mixed exact and wildcard patterns."""
        from acme2certifier.acme_srv.helpers.domain_utils import is_email_whitelisted

        email_list = ["*@example.com", "special@foo.com"]
        self.assertTrue(
            is_email_whitelisted(self.logger, "user@example.com", email_list)
        )
        self.assertTrue(
            is_email_whitelisted(self.logger, "special@foo.com", email_list)
        )
        self.assertFalse(
            is_email_whitelisted(self.logger, "nobody@bar.com", email_list)
        )

    def test_543_is_email_whitelisted_strip_and_case(self):
        """Test is_email_whitelisted is case and whitespace insensitive."""
        from acme2certifier.acme_srv.helpers.domain_utils import is_email_whitelisted

        email_list = ["  User@Example.com  ", "*@foo.com"]
        self.assertTrue(
            is_email_whitelisted(self.logger, " user@example.com ", email_list)
        )
        self.assertTrue(is_email_whitelisted(self.logger, "ADMIN@FOO.COM", email_list))


if __name__ == "__main__":
    unittest.main()
