From 1f0f432327a6f86490e8c3ce588f4b36e63a37f0 Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Mon, 25 Jun 2018 18:42:18 +0300 Subject: [PATCH] Fix unit tests certificates to have correct chains and private keys In preparation for certificate integrity-checking: invalid certificate chains and mismatching private keys will no longer be allowed anywhere in Lemur code. The test vector certs were generated using the Lemur "cryptography" authority plugin. * Certificates are now more similar to real-world usage: long serial numbers, etc. * Private key is included for all certs, so it's easy to re-generate anything if needed. --- lemur/plugins/lemur_aws/tests/test_iam.py | 4 +- lemur/plugins/lemur_slack/tests/test_slack.py | 2 +- lemur/tests/conf.py | 3 +- lemur/tests/conftest.py | 4 +- lemur/tests/factories.py | 21 +- lemur/tests/plugins/issuer_plugin.py | 11 +- lemur/tests/test_certificates.py | 52 +-- lemur/tests/test_defaults.py | 26 +- lemur/tests/test_pending_certificates.py | 7 +- lemur/tests/test_sources.py | 7 +- lemur/tests/test_validators.py | 4 +- lemur/tests/test_verify.py | 5 +- lemur/tests/vectors.py | 346 ++++++++++++------ 13 files changed, 310 insertions(+), 182 deletions(-) diff --git a/lemur/plugins/lemur_aws/tests/test_iam.py b/lemur/plugins/lemur_aws/tests/test_iam.py index 4561a253..deec221e 100644 --- a/lemur/plugins/lemur_aws/tests/test_iam.py +++ b/lemur/plugins/lemur_aws/tests/test_iam.py @@ -1,7 +1,7 @@ import pytest from moto import mock_iam, mock_sts -from lemur.tests.vectors import EXTERNAL_VALID_STR, PRIVATE_KEY_STR +from lemur.tests.vectors import EXTERNAL_VALID_STR, SAN_CERT_KEY def test_get_name_from_arn(): @@ -15,6 +15,6 @@ def test_get_name_from_arn(): @mock_iam() def test_get_all_server_certs(app): from lemur.plugins.lemur_aws.iam import upload_cert, get_all_certificates - upload_cert('123456789012', 'testCert', EXTERNAL_VALID_STR, PRIVATE_KEY_STR) + upload_cert('123456789012', 'testCert', EXTERNAL_VALID_STR, SAN_CERT_KEY) certs = get_all_certificates('123456789012') assert len(certs) == 1 diff --git a/lemur/plugins/lemur_slack/tests/test_slack.py b/lemur/plugins/lemur_slack/tests/test_slack.py index 140208ed..701f69d9 100644 --- a/lemur/plugins/lemur_slack/tests/test_slack.py +++ b/lemur/plugins/lemur_slack/tests/test_slack.py @@ -16,7 +16,7 @@ def test_formatting(certificate): }, { 'short': True, - 'value': u'Wednesday, January 1, 2020', + 'value': u'Tuesday, December 31, 2047', 'title': 'Expires' }, { 'short': True, diff --git a/lemur/tests/conf.py b/lemur/tests/conf.py index a815230b..b79f527d 100644 --- a/lemur/tests/conf.py +++ b/lemur/tests/conf.py @@ -23,7 +23,8 @@ LEMUR_ENCRYPTION_KEYS = 'o61sBLNBSGtAckngtNrfVNd8xy8Hp9LBGDstTbMbqCY=' # List of domain regular expressions that non-admin users can issue LEMUR_WHITELISTED_DOMAINS = [ - '^[a-zA-Z0-9-]+\.example\.com$' + '^[a-zA-Z0-9-]+\.example\.com$', + '^[a-zA-Z0-9-]+\.example\.org$', ] # Mail Server diff --git a/lemur/tests/conftest.py b/lemur/tests/conftest.py index 69b33a9f..fcd3005d 100644 --- a/lemur/tests/conftest.py +++ b/lemur/tests/conftest.py @@ -11,7 +11,7 @@ from flask_principal import identity_changed, Identity from lemur import create_app from lemur.database import db as _db from lemur.auth.service import create_token -from lemur.tests.vectors import PRIVATE_KEY_STR +from lemur.tests.vectors import SAN_CERT_KEY from .factories import ApiKeyFactory, AuthorityFactory, NotificationFactory, DestinationFactory, \ CertificateFactory, UserFactory, RoleFactory, SourceFactory, EndpointFactory, \ @@ -228,7 +228,7 @@ def logged_in_admin(session, app): @pytest.fixture def private_key(): - return load_pem_private_key(PRIVATE_KEY_STR.encode(), password=None, backend=default_backend()) + return load_pem_private_key(SAN_CERT_KEY.encode(), password=None, backend=default_backend()) @pytest.fixture diff --git a/lemur/tests/factories.py b/lemur/tests/factories.py index 815c958d..eb9d2b97 100644 --- a/lemur/tests/factories.py +++ b/lemur/tests/factories.py @@ -19,7 +19,8 @@ from lemur.endpoints.models import Policy, Endpoint from lemur.policies.models import RotationPolicy from lemur.api_keys.models import ApiKey -from .vectors import INTERNAL_VALID_SAN_STR, PRIVATE_KEY_STR, CSR_STR +from .vectors import SAN_CERT_STR, SAN_CERT_KEY, CSR_STR, INTERMEDIATE_CERT_STR, ROOTCA_CERT_STR, INTERMEDIATE_KEY, \ + WILDCARD_CERT_KEY class BaseFactory(SQLAlchemyModelFactory): @@ -34,9 +35,9 @@ class BaseFactory(SQLAlchemyModelFactory): class CertificateFactory(BaseFactory): """Certificate factory.""" name = Sequence(lambda n: 'certificate{0}'.format(n)) - chain = INTERNAL_VALID_SAN_STR - body = INTERNAL_VALID_SAN_STR - private_key = PRIVATE_KEY_STR + chain = INTERMEDIATE_CERT_STR + body = SAN_CERT_STR + private_key = SAN_CERT_KEY owner = 'joe@example.com' status = FuzzyChoice(['valid', 'revoked', 'unknown']) deleted = False @@ -119,13 +120,19 @@ class CertificateFactory(BaseFactory): self.roles.append(domain) +class CACertificateFactory(CertificateFactory): + chain = ROOTCA_CERT_STR + body = INTERMEDIATE_CERT_STR + private_key = INTERMEDIATE_KEY + + class AuthorityFactory(BaseFactory): """Authority factory.""" name = Sequence(lambda n: 'authority{0}'.format(n)) owner = 'joe@example.com' plugin = {'slug': 'test-issuer'} description = FuzzyText(length=128) - authority_certificate = SubFactory(CertificateFactory) + authority_certificate = SubFactory(CACertificateFactory) class Meta: """Factory configuration.""" @@ -299,8 +306,8 @@ class PendingCertificateFactory(BaseFactory): name = Sequence(lambda n: 'pending_certificate{0}'.format(n)) external_id = 12345 csr = CSR_STR - chain = INTERNAL_VALID_SAN_STR - private_key = PRIVATE_KEY_STR + chain = INTERMEDIATE_CERT_STR + private_key = WILDCARD_CERT_KEY owner = 'joe@example.com' status = FuzzyChoice(['valid', 'revoked', 'unknown']) deleted = False diff --git a/lemur/tests/plugins/issuer_plugin.py b/lemur/tests/plugins/issuer_plugin.py index 7dbc46de..3fda83ae 100644 --- a/lemur/tests/plugins/issuer_plugin.py +++ b/lemur/tests/plugins/issuer_plugin.py @@ -1,6 +1,6 @@ from lemur.plugins.bases import IssuerPlugin -from lemur.tests.vectors import INTERNAL_VALID_SAN_STR, INTERNAL_VALID_LONG_STR +from lemur.tests.vectors import SAN_CERT_STR, INTERMEDIATE_CERT_STR class TestIssuerPlugin(IssuerPlugin): @@ -15,12 +15,13 @@ class TestIssuerPlugin(IssuerPlugin): super(TestIssuerPlugin, self).__init__(*args, **kwargs) def create_certificate(self, csr, issuer_options): - return INTERNAL_VALID_LONG_STR, INTERNAL_VALID_SAN_STR, None + # body, chain, external_id + return SAN_CERT_STR, INTERMEDIATE_CERT_STR, None @staticmethod def create_authority(options): role = {'username': '', 'password': '', 'name': 'test'} - return INTERNAL_VALID_SAN_STR, "", [role] + return SAN_CERT_STR, "", [role] class TestAsyncIssuerPlugin(IssuerPlugin): @@ -38,12 +39,12 @@ class TestAsyncIssuerPlugin(IssuerPlugin): return "", "", 12345 def get_ordered_certificate(self, pending_cert): - return INTERNAL_VALID_LONG_STR, INTERNAL_VALID_SAN_STR, 54321 + return INTERMEDIATE_CERT_STR, SAN_CERT_STR, 54321 @staticmethod def create_authority(options): role = {'username': '', 'password': '', 'name': 'test'} - return INTERNAL_VALID_SAN_STR, "", [role] + return SAN_CERT_STR, "", [role] def cancel_ordered_certificate(self, pending_certificate, **kwargs): return True diff --git a/lemur/tests/test_certificates.py b/lemur/tests/test_certificates.py index fff6e253..91fdc45d 100644 --- a/lemur/tests/test_certificates.py +++ b/lemur/tests/test_certificates.py @@ -18,25 +18,27 @@ from lemur.domains.models import Domain from lemur.tests.vectors import VALID_ADMIN_API_TOKEN, VALID_ADMIN_HEADER_TOKEN, VALID_USER_HEADER_TOKEN, CSR_STR, \ - INTERNAL_VALID_LONG_STR, INTERNAL_VALID_SAN_STR, PRIVATE_KEY_STR + INTERMEDIATE_CERT_STR, SAN_CERT_STR, SAN_CERT_KEY def test_get_or_increase_name(session, certificate): from lemur.certificates.models import get_or_increase_name from lemur.tests.factories import CertificateFactory - assert get_or_increase_name(certificate.name, certificate.serial) == '{0}-3E9'.format(certificate.name) + serial = 'AFF2DB4F8D2D4D8E80FA382AE27C2333' + + assert get_or_increase_name(certificate.name, certificate.serial) == '{0}-{1}'.format(certificate.name, serial) certificate.name = 'test-cert-11111111' - assert get_or_increase_name(certificate.name, certificate.serial) == 'test-cert-11111111-3E9' + assert get_or_increase_name(certificate.name, certificate.serial) == 'test-cert-11111111-' + serial certificate.name = 'test-cert-11111111-1' - assert get_or_increase_name('test-cert-11111111-1', certificate.serial) == 'test-cert-11111111-1-3E9' + assert get_or_increase_name('test-cert-11111111-1', certificate.serial) == 'test-cert-11111111-1-' + serial - cert2 = CertificateFactory(name='certificate1-3E9') + cert2 = CertificateFactory(name='certificate1-' + serial) session.commit() - assert get_or_increase_name('certificate1', 1001) == 'certificate1-3E9-1' + assert get_or_increase_name('certificate1', int(serial, 16)) == 'certificate1-{}-1'.format(serial) def test_get_certificate_primitives(certificate): @@ -59,7 +61,7 @@ def test_certificate_output_schema(session, certificate, issuer_plugin): # Make sure serialization parses the cert only once (uses cached 'parsed_cert' attribute) with patch('lemur.common.utils.parse_certificate', side_effect=utils.parse_certificate) as wrapper: data, errors = CertificateOutputSchema().dump(certificate) - assert data['issuer'] == 'Example' + assert data['issuer'] == 'LemurTrustEnterprisesLtd' assert wrapper.call_count == 1 @@ -149,8 +151,8 @@ def test_certificate_input_schema(client, authority): 'owner': 'jim@example.com', 'authority': {'id': authority.id}, 'description': 'testtestest', - 'validityEnd': arrow.get(2016, 11, 9).isoformat(), - 'validityStart': arrow.get(2015, 11, 9).isoformat(), + 'validityStart': arrow.get(2018, 11, 9).isoformat(), + 'validityEnd': arrow.get(2019, 11, 9).isoformat(), 'dnsProvider': None, } @@ -445,16 +447,16 @@ def test_get_account_number(client): def test_mint_certificate(issuer_plugin, authority): from lemur.certificates.service import mint cert_body, private_key, chain, external_id, csr = mint(authority=authority, csr=CSR_STR) - assert cert_body == INTERNAL_VALID_LONG_STR, INTERNAL_VALID_SAN_STR + assert cert_body == SAN_CERT_STR def test_create_certificate(issuer_plugin, authority, user): from lemur.certificates.service import create cert = create(authority=authority, csr=CSR_STR, owner='joe@example.com', creator=user['user']) - assert str(cert.not_after) == '2040-01-01T20:30:52+00:00' - assert str(cert.not_before) == '2015-06-26T20:30:52+00:00' - assert cert.issuer == 'Example' - assert cert.name == 'long.lived.com-Example-20150626-20400101' + assert str(cert.not_after) == '2047-12-31T22:00:00+00:00' + assert str(cert.not_before) == '2017-12-31T22:00:00+00:00' + assert cert.issuer == 'LemurTrustEnterprisesLtd' + assert cert.name == 'SAN-san.example.org-LemurTrustEnterprisesLtd-20171231-20471231-AFF2DB4F8D2D4D8E80FA382AE27C2333' cert = create(authority=authority, csr=CSR_STR, owner='joe@example.com', name='ACustomName1', creator=user['user']) assert cert.name == 'ACustomName1' @@ -481,33 +483,33 @@ def test_create_csr(): def test_import(user): from lemur.certificates.service import import_certificate - cert = import_certificate(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, creator=user['user']) - assert str(cert.not_after) == '2040-01-01T20:30:52+00:00' - assert str(cert.not_before) == '2015-06-26T20:30:52+00:00' - assert cert.issuer == 'Example' - assert cert.name == 'long.lived.com-Example-20150626-20400101-2' + cert = import_certificate(body=SAN_CERT_STR, chain=INTERMEDIATE_CERT_STR, private_key=SAN_CERT_KEY, creator=user['user']) + assert str(cert.not_after) == '2047-12-31T22:00:00+00:00' + assert str(cert.not_before) == '2017-12-31T22:00:00+00:00' + assert cert.issuer == 'LemurTrustEnterprisesLtd' + assert cert.name == 'SAN-san.example.org-LemurTrustEnterprisesLtd-20171231-20471231-AFF2DB4F8D2D4D8E80FA382AE27C2333-2' - cert = import_certificate(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com', name='ACustomName2', creator=user['user']) + cert = import_certificate(body=SAN_CERT_STR, chain=INTERMEDIATE_CERT_STR, private_key=SAN_CERT_KEY, owner='joe@example.com', name='ACustomName2', creator=user['user']) assert cert.name == 'ACustomName2' @pytest.mark.skip def test_upload(user): from lemur.certificates.service import upload - cert = upload(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com', creator=user['user']) + cert = upload(body=SAN_CERT_STR, chain=INTERMEDIATE_CERT_STR, private_key=SAN_CERT_KEY, owner='joe@example.com', creator=user['user']) assert str(cert.not_after) == '2040-01-01T20:30:52+00:00' assert str(cert.not_before) == '2015-06-26T20:30:52+00:00' assert cert.issuer == 'Example' assert cert.name == 'long.lived.com-Example-20150626-20400101-3' - cert = upload(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com', name='ACustomName', creator=user['user']) + cert = upload(body=SAN_CERT_STR, chain=INTERMEDIATE_CERT_STR, private_key=SAN_CERT_KEY, owner='joe@example.com', name='ACustomName', creator=user['user']) assert 'ACustomName' in cert.name # verify upload with a private key as a str def test_upload_private_key_str(user): from lemur.certificates.service import upload - cert = upload(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com', name='ACustomName', creator=user['user']) + cert = upload(body=SAN_CERT_STR, chain=INTERMEDIATE_CERT_STR, private_key=SAN_CERT_KEY, owner='joe@example.com', name='ACustomName', creator=user['user']) assert cert @@ -533,8 +535,8 @@ def test_certificate_get(client, token, status): def test_certificate_get_body(client): response_body = client.get(api.url_for(Certificates, certificate_id=1), headers=VALID_USER_HEADER_TOKEN).json - assert response_body['serial'] == '1001' - assert response_body['serialHex'] == '3E9' + assert response_body['serial'] == '211983098819107449768450703123665283596' + assert response_body['serialHex'] == '9F7A75B39DAE4C3F9524C68B06DA6A0C' @pytest.mark.parametrize("token,status", [ diff --git a/lemur/tests/test_defaults.py b/lemur/tests/test_defaults.py index a72689cc..c6c70684 100644 --- a/lemur/tests/test_defaults.py +++ b/lemur/tests/test_defaults.py @@ -1,45 +1,41 @@ +from .vectors import SAN_CERT, WILDCARD_CERT, INTERMEDIATE_CERT def test_cert_get_cn(client): - from .vectors import INTERNAL_VALID_LONG_CERT from lemur.common.defaults import common_name - assert common_name(INTERNAL_VALID_LONG_CERT) == 'long.lived.com' + assert common_name(SAN_CERT) == 'san.example.org' def test_cert_sub_alt_domains(client): - from .vectors import INTERNAL_VALID_SAN_CERT, INTERNAL_VALID_LONG_CERT from lemur.common.defaults import domains - assert domains(INTERNAL_VALID_LONG_CERT) == [] - assert domains(INTERNAL_VALID_SAN_CERT) == ['example2.long.com', 'example3.long.com'] + assert domains(INTERMEDIATE_CERT) == [] + assert domains(SAN_CERT) == ['san.example.org', 'san2.example.org', 'daniel-san.example.org'] def test_cert_is_san(client): - from .vectors import INTERNAL_VALID_SAN_CERT, INTERNAL_VALID_LONG_CERT from lemur.common.defaults import san - assert not san(INTERNAL_VALID_LONG_CERT) - assert san(INTERNAL_VALID_SAN_CERT) + assert san(SAN_CERT) + # Wildcard cert has just one SAN record that matches the common name + assert not san(WILDCARD_CERT) def test_cert_is_wildcard(client): - from .vectors import INTERNAL_VALID_WILDCARD_CERT, INTERNAL_VALID_LONG_CERT from lemur.common.defaults import is_wildcard - assert is_wildcard(INTERNAL_VALID_WILDCARD_CERT) - assert not is_wildcard(INTERNAL_VALID_LONG_CERT) + assert is_wildcard(WILDCARD_CERT) + assert not is_wildcard(INTERMEDIATE_CERT) def test_cert_bitstrength(client): - from .vectors import INTERNAL_VALID_LONG_CERT from lemur.common.defaults import bitstrength - assert bitstrength(INTERNAL_VALID_LONG_CERT) == 2048 + assert bitstrength(INTERMEDIATE_CERT) == 2048 def test_cert_issuer(client): - from .vectors import INTERNAL_VALID_LONG_CERT from lemur.common.defaults import issuer - assert issuer(INTERNAL_VALID_LONG_CERT) == 'Example' + assert issuer(INTERMEDIATE_CERT) == 'LemurTrustEnterprisesLtd' def test_text_to_slug(client): diff --git a/lemur/tests/test_pending_certificates.py b/lemur/tests/test_pending_certificates.py index c90ecb35..455a4068 100644 --- a/lemur/tests/test_pending_certificates.py +++ b/lemur/tests/test_pending_certificates.py @@ -2,7 +2,8 @@ import json import pytest -from .vectors import CSR_STR, INTERNAL_VALID_LONG_STR, VALID_ADMIN_API_TOKEN, VALID_ADMIN_HEADER_TOKEN, VALID_USER_HEADER_TOKEN +from .vectors import CSR_STR, INTERMEDIATE_CERT_STR, VALID_ADMIN_API_TOKEN, VALID_ADMIN_HEADER_TOKEN, \ + VALID_USER_HEADER_TOKEN, WILDCARD_CERT_STR from lemur.pending_certificates.views import * # noqa @@ -23,8 +24,8 @@ def test_create_pending_certificate(async_issuer_plugin, async_authority, user): def test_create_pending(pending_certificate, user, session): import copy from lemur.pending_certificates.service import create_certificate, get - cert = {'body': INTERNAL_VALID_LONG_STR, - 'chain': None, + cert = {'body': WILDCARD_CERT_STR, + 'chain': INTERMEDIATE_CERT_STR, 'external_id': 54321} # Weird copy because the session behavior. pending_certificate is a valid object but the diff --git a/lemur/tests/test_sources.py b/lemur/tests/test_sources.py index a545d51a..1ce0d9ba 100644 --- a/lemur/tests/test_sources.py +++ b/lemur/tests/test_sources.py @@ -2,7 +2,8 @@ import pytest from lemur.sources.views import * # noqa -from .vectors import VALID_ADMIN_API_TOKEN, VALID_ADMIN_HEADER_TOKEN, VALID_USER_HEADER_TOKEN, INTERNAL_PRIVATE_KEY_A_STR, INTERNAL_VALID_WILDCARD_STR +from .vectors import VALID_ADMIN_API_TOKEN, VALID_ADMIN_HEADER_TOKEN, VALID_USER_HEADER_TOKEN, WILDCARD_CERT_STR, \ + WILDCARD_CERT_KEY def validate_source_schema(client): @@ -25,8 +26,8 @@ def test_create_certificate(user, source): certificate_create({}, source) data = { - 'body': INTERNAL_VALID_WILDCARD_STR, - 'private_key': INTERNAL_PRIVATE_KEY_A_STR, + 'body': WILDCARD_CERT_STR, + 'private_key': WILDCARD_CERT_KEY, 'owner': 'bob@example.com', 'creator': user['user'] } diff --git a/lemur/tests/test_validators.py b/lemur/tests/test_validators.py index b9489ef2..815b7c9d 100644 --- a/lemur/tests/test_validators.py +++ b/lemur/tests/test_validators.py @@ -1,13 +1,13 @@ import pytest from datetime import datetime -from .vectors import PRIVATE_KEY_STR +from .vectors import SAN_CERT_KEY from marshmallow.exceptions import ValidationError def test_private_key(session): from lemur.common.validators import private_key - private_key(PRIVATE_KEY_STR) + private_key(SAN_CERT_KEY) with pytest.raises(ValidationError): private_key('invalid_private_key') diff --git a/lemur/tests/test_verify.py b/lemur/tests/test_verify.py index 6b0f79a7..4a7854b2 100644 --- a/lemur/tests/test_verify.py +++ b/lemur/tests/test_verify.py @@ -5,15 +5,16 @@ from cryptography.hazmat.primitives import serialization, hashes from cryptography.x509 import UniformResourceIdentifier from lemur.certificates.verify import verify_string, crl_verify -from lemur.tests.vectors import INTERNAL_VALID_LONG_STR from lemur.utils import mktempfile +from .vectors import INTERMEDIATE_CERT_STR + def test_verify_simple_cert(): """Simple certificate without CRL or OCSP.""" # Verification raises an exception for "unknown" if there are no means to verify it with pytest.raises(Exception, match="Failed to verify"): - verify_string(INTERNAL_VALID_LONG_STR, '') + verify_string(INTERMEDIATE_CERT_STR, '') def test_verify_crl_unknown_scheme(cert_builder, private_key): diff --git a/lemur/tests/vectors.py b/lemur/tests/vectors.py index 0c4c732f..6a836b30 100644 --- a/lemur/tests/vectors.py +++ b/lemur/tests/vectors.py @@ -18,35 +18,242 @@ VALID_ADMIN_API_TOKEN = { } -INTERNAL_VALID_LONG_STR = """ +#: CN=LemurTrust Unittests Root CA 2018 +ROOTCA_CERT_STR = """\ -----BEGIN CERTIFICATE----- -MIID1zCCAr+gAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCVVMx -CzAJBgNVBAgMAkNBMRAwDgYDVQQHDAdBIHBsYWNlMRcwFQYDVQQDDA5sb25nLmxp -dmVkLmNvbTEQMA4GA1UECgwHRXhhbXBsZTETMBEGA1UECwwKT3BlcmF0aW9uczEe -MBwGCSqGSIb3DQEJARYPamltQGV4YW1wbGUuY29tMB4XDTE1MDYyNjIwMzA1MloX -DTQwMDEwMTIwMzA1MlowgYwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEQMA4G -A1UEBwwHQSBwbGFjZTEXMBUGA1UEAwwObG9uZy5saXZlZC5jb20xEDAOBgNVBAoM -B0V4YW1wbGUxEzARBgNVBAsMCk9wZXJhdGlvbnMxHjAcBgkqhkiG9w0BCQEWD2pp -bUBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKeg -sqb0HI10i2eRSx3pLeA7JoGdUpud7hy3bGws/1HgOSpRMin9Y65DEpVq2Ia9oir7 -XOJLpSTEIulnBkgDHNOsdKVYHDR6k0gUisnIKSl2C3IgKHpCouwiOvvVPwd3PExg -17+d7KLBIu8LpG28wkXKFU8vSz5i7H4i/XCEChnKJ4oGJuGAJJM4Zn022U156pco -97aEAc9ZXR/1dm2njr4XxCXmrnKCYTElfRhLkmxtv+mCi6eV//5d12z7mY3dTBkQ -EG2xpb5DQ+ITQ8BzsKcPX80rz8rTzgYFwaV3gUg38+bgka/JGJq8HgBuNnHv5CeT -1T/EoZTRYW2oPfOgQK8CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B -Af8EBAMCAQYwHQYDVR0OBBYEFIuDY73dQIhj2nnd4DG2SvseHVVaMA0GCSqGSIb3 -DQEBCwUAA4IBAQBk/WwfoWYdS0M8rz5tJda/cMdYFSugUbTn6JJdmHuw6RmiKzKG -8NzfSqBR6m8MWdSTuAZ/chsUZH9YEIjS9tAH9/FfUFBrsUE7TXaUgpNBm4DBLLfl -fj5xDmEyj17JPN/C36amQ9eU5BNesdCx9EkdWLyVJaM50HFRo71W0/FrpKZyKK68 -XPhd1z9w/xgfCfYhe7PjEmrmNPN5Tgk5TyXW+UUhOepDctAv2DBetptcx+gHrtW+ -Ygk1wptlt/tg7uUmstmXZA4vTPx83f4P3KSS3XHIYFIyGFWUDs23C20K6mmW1iXa -h0S8LN4iv/+vNFPNiM1z9X/SZgfbwZXrLsSi +MIIEFjCCAv6gAwIBAgIQbIbX/Ap0Roqzf5HeN5akmzANBgkqhkiG9w0BAQsFADCB +pDEqMCgGA1UEAwwhTGVtdXJUcnVzdCBVbml0dGVzdHMgUm9vdCBDQSAyMDE4MSMw +IQYDVQQKDBpMZW11clRydXN0IEVudGVycHJpc2VzIEx0ZDEmMCQGA1UECwwdVW5p +dHRlc3RpbmcgT3BlcmF0aW9ucyBDZW50ZXIxCzAJBgNVBAYTAkVFMQwwCgYDVQQI +DANOL0ExDjAMBgNVBAcMBUVhcnRoMB4XDTE3MTIzMTIyMDAwMFoXDTQ3MTIzMTIy +MDAwMFowgaQxKjAoBgNVBAMMIUxlbXVyVHJ1c3QgVW5pdHRlc3RzIFJvb3QgQ0Eg +MjAxODEjMCEGA1UECgwaTGVtdXJUcnVzdCBFbnRlcnByaXNlcyBMdGQxJjAkBgNV +BAsMHVVuaXR0ZXN0aW5nIE9wZXJhdGlvbnMgQ2VudGVyMQswCQYDVQQGEwJFRTEM +MAoGA1UECAwDTi9BMQ4wDAYDVQQHDAVFYXJ0aDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAL8laXtLXyM64t5dz2B9q+4VvOsChefBi2PlGudqxDuRN3l0 +Kmcfun6x2Gng24pTlGdtmiTEWA0a2F8HRLv4YBWhuYleVeBPtf1fF1/SuYgkJOWT +7S5qk/od/tUOLHS0Y067st3FydnFQTKpAuYveEkxleFrMS8hX8cuEgbER+8ybiXK +n4GsyM/om6lsTyBoaLp5yTAoQb4jAWDbiz1xcjPSkvH2lm7rLGtKoylCYwxRsMh2 +nZcRr1OXVhYHXwpYHVB/jVAjy7PAWQ316hi6mpPYbBV+yfn2GUfGuytqyoXLEsrM +3iEEAkU0mJjQmYsCDM3r7ONHTM+UFEk47HCZJccCAwEAAaNCMEAwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFFL12SFeOTTDdGKsHKoz +eByGHY6nMA0GCSqGSIb3DQEBCwUAA4IBAQAJfe0/uAHobkxth38dqrSFmTo+D5/T +MlRt3hdgjlah6sD2+/DObCyut/XhQWCgTNWyRi4xTKgLh5KSoeJ9EMkADGEgDkU2 +vjBg5FmGZsxg6bqjxehK+2HvASJoTH8r41xmTioav7a2i3wNhaNSntw2QRTQBQED +OIzHRpPDQ2quErjA8nSifE2xmAAr3g+FuookTTJuv37s2cS59zRYsg+WC3+TtPpR +ssvobJ6Xe2D4cCVjUmsqtFEztMgdqgmlcWyGdUKeXdi7CMoeTb4uO+9qRQq46wYW +n7K1z+W0Kp5yhnnPAoOioAP4vjASDx3z3RnLaZvMmcO7YdCIwhE5oGV0 -----END CERTIFICATE----- """ -INTERNAL_VALID_LONG_CERT = parse_certificate(INTERNAL_VALID_LONG_STR) +ROOTCA_KEY = """\ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAvyVpe0tfIzri3l3PYH2r7hW86wKF58GLY+Ua52rEO5E3eXQq +Zx+6frHYaeDbilOUZ22aJMRYDRrYXwdEu/hgFaG5iV5V4E+1/V8XX9K5iCQk5ZPt +LmqT+h3+1Q4sdLRjTruy3cXJ2cVBMqkC5i94STGV4WsxLyFfxy4SBsRH7zJuJcqf +gazIz+ibqWxPIGhounnJMChBviMBYNuLPXFyM9KS8faWbussa0qjKUJjDFGwyHad +lxGvU5dWFgdfClgdUH+NUCPLs8BZDfXqGLqak9hsFX7J+fYZR8a7K2rKhcsSysze +IQQCRTSYmNCZiwIMzevs40dMz5QUSTjscJklxwIDAQABAoIBAAyVzwMiLEpqhyNy +88N7osVTQxQKH3zp3l6eaA4SlocBgbCKeHw/t4y98uzNtEbASAYjTkHbd5ytRs/C +78Cckt75vfiQcIELXoUnLKfPfQ28q30+JyCmPcX7EZs/iqfIdL1rWFSHwEmJVkia +nik/uODA1gh4gU2EGgVIQEGXzNCv2RgTgmuyY+/4LbgEnUdMF+/umDhQd+o+nnL3 +Ie0eJ7mTNPq78Dw6/21OcpE3j+yBIHGf5ZOHf5Qy+kBAytR7n+wzorkVYhbTvb4s +aWzHzmNBViQcum2SOaa/5I/HiG/Z4R2vnD53+bbjeLAsT/4OgUMdWziKOQbGbWwp +z+j/tekCgYEA8cfyOrbvkTLQHpC/1PC0GyrPGW+/5HKv34N+lCK4U+j6q5x7T7ia +kIacvW3/gPsmW0zcdty1RfgEKQXOT7sK7YN1yMwfRwHX7Ea9TW9ZPW/gnOlhwVJ0 +Fx2SNESLmubi2cjEMayI9I++pDzwPMTLWNj53kgBhB/Qhw6+N74ScL0CgYEAymMm +JKVu3eNzooVIjS0wwlEpsteQZa1PI26QOyN/sr8wgbVrb/6P/dNc7Bl3YUMe0ZyR +ejyFo1bLsFemsWCZKWdgVOCQG1DqtHOPQSqkZPfYKfoMY9LWemyPk61CQDWzL3tg +L742V0iVPtYmtysKqagFFNeVML91duLWiobDwtMCgYAkl+2Kg2uI31bueVv/X5ry +zazgnbA+ZDlIK/+5bfPWB1oBJULokvkZzLXmWcKlA94PTXfEqazp9Rq0FsPd/2It +BouKI5LMTXQft6kpEiRAjzFArnX0K4WUhg49yO4UOMO20JMZLZLg6OyisPJvUB2y +ycwvn1hTZflKp6mUiDkERQKBgBUDyJEjkGh/1qD4f/kQyTBUJyVH1tmH7mC6eUV6 +wSa5TXsacGZ3o1Hy4YIufsPdqVSQklaD9EhqmcncwBVI935iGpGVo8ECXOyR1z0o +BVvqlEp/iUvQN68MmLf31JpAOTPj9q/ea1wS0FRu/iQk1v2Y0bZBUF94ceT/VtGZ +frg7AoGBAI3iNhiZMQrq6j8kaEgDea+T1Ui0rGYIeD60TAuHfJ0a50Ga4rPp0u2p +G92Mk0sk2VGzZCkV6YRd/DJBXsqDAGeaEKzEnXiDBObUORDIo9SL3YhzosH191Ce +45ZXINAgovSzBcZfwStWjebUDw4v10Arc6ipkHGBPbK556S6wXGK +-----END RSA PRIVATE KEY----- +""" -INTERNAL_INVALID_STR = """ +#: CN=LemurTrust Unittests Class 1 CA 2018 +INTERMEDIATE_CERT_STR = """\ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwKgAwIBAgIRAJ96dbOdrkw/lSTGiwbaagwwDQYJKoZIhvcNAQELBQAw +gaQxKjAoBgNVBAMMIUxlbXVyVHJ1c3QgVW5pdHRlc3RzIFJvb3QgQ0EgMjAxODEj +MCEGA1UECgwaTGVtdXJUcnVzdCBFbnRlcnByaXNlcyBMdGQxJjAkBgNVBAsMHVVu +aXR0ZXN0aW5nIE9wZXJhdGlvbnMgQ2VudGVyMQswCQYDVQQGEwJFRTEMMAoGA1UE +CAwDTi9BMQ4wDAYDVQQHDAVFYXJ0aDAeFw0xNzEyMzEyMjAwMDBaFw00NzEyMzEy +MjAwMDBaMIGnMS0wKwYDVQQDDCRMZW11clRydXN0IFVuaXR0ZXN0cyBDbGFzcyAx +IENBIDIwMTgxIzAhBgNVBAoMGkxlbXVyVHJ1c3QgRW50ZXJwcmlzZXMgTHRkMSYw +JAYDVQQLDB1Vbml0dGVzdGluZyBPcGVyYXRpb25zIENlbnRlcjELMAkGA1UEBhMC +RUUxDDAKBgNVBAgMA04vQTEOMAwGA1UEBwwFRWFydGgwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDR+qNdfNsLhGvgw3IgCQNakL2B9dpQtkVnvAXhdRZq +JETm/tHLkGvONWTXAwGdoiKv6+0j3I5InUsW+wzUPewcfj+PLNu4mFMq8jH/gPhT +ElKiAztPRdm8QKchvrqiaU6uEbia8ClM6uPpIi8StxE1aJRYL03p0WeMJjJPrsl6 +eSSdpR4qL69GTd1n5je9OuWAcn5utXXnt/jO4vNeFRjlGp/0n3JmTDd9w4vtAyY9 +UrdGgo37eBmi6mXt5J9i//NenhaiOVU81RqxZM2Jt1kkg2WSjcqcIQfBEWp9StG4 +6VmHLaL+9/v2XAV3tL1VilJGj6PoFMb4gY5MXthfGSiXAgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQstpQr0iMBVfv0 +lODIsMgT9+9oezANBgkqhkiG9w0BAQsFAAOCAQEASYQbv1Qwb5zES6Gb5LEhrAcH +81ZB2uIpKd3Ki6AS4fLJVymMGkUs0RZjt39Ep4qX1zf0hn82Yh9YwRalrkgu+tzK +rp0JgegNe6+gyFRrJC0SIGA4zc3M02m/n4tdaouU2lp6jhmWruL3g25ZkgbQ8LO2 +zjpSMtblR2euvR2+bI7TepklyG71qx5y6/N8x5PT+hnTlleiZeE/ji9D96MZlpWB +4kBihekWmxuptED22z/tpQtac+hPBNgt8z1uFVEYN2rKEcCE7V6Qk7icS+M4Vb7M +3D8kLyWDubs9Yy3l0EWjOXQXxEhTaKEm4gSuY/j+Y35bBVkA2Fcyuq7msiTgrw== +-----END CERTIFICATE----- +""" +INTERMEDIATE_CERT = parse_certificate(INTERMEDIATE_CERT_STR) +INTERMEDIATE_KEY = """\ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA0fqjXXzbC4Rr4MNyIAkDWpC9gfXaULZFZ7wF4XUWaiRE5v7R +y5BrzjVk1wMBnaIir+vtI9yOSJ1LFvsM1D3sHH4/jyzbuJhTKvIx/4D4UxJSogM7 +T0XZvECnIb66omlOrhG4mvApTOrj6SIvErcRNWiUWC9N6dFnjCYyT67JenkknaUe +Ki+vRk3dZ+Y3vTrlgHJ+brV157f4zuLzXhUY5Rqf9J9yZkw3fcOL7QMmPVK3RoKN ++3gZoupl7eSfYv/zXp4WojlVPNUasWTNibdZJINlko3KnCEHwRFqfUrRuOlZhy2i +/vf79lwFd7S9VYpSRo+j6BTG+IGOTF7YXxkolwIDAQABAoIBAQC8dTuSeLEQUTWR +cVlIr043RpkPv1zF/BGm3PZaOAB6GztMJ4CcN27KkNmEsMoOdKq1QgaAnT+GpMX0 +RjZpd3omyJi7JAPAVdavQNjm/RXjWRqZFlVw/LxDXbOjcc+IXQOk73rEdLBcvKT5 +ZRjirzPev5IE49AF/0/0VYPqSHHEXL1HMWy5Q7KZU/C4Yp8em2l3UAh1/nLI2L+U +iw6DxBhBbdsc2vD4dd4UUQmznBfvdBOiejKs9DYIDzmTrGI2lH0VUU6PVzb9LKJ3 +UtlIsjOO0FdJxXhkjsDCcF4eEMhO4qOfVJDcl0YYsPLjM0t4IVfe2C0b3Hd37hhF +b3ux0YoBAoGBAPWCPBepUdtiiMM21dLFPuy/d9/C3k8xTD23aO8zupwnGD1zz8OY +1GzsCtR9me0nIbHGxT+Unovuxh2JYQgrFpAFsG/izL8SpkDeT3hJDPY8PLrhGqMS +RBcYYgZ+1aNZTPZRKDjTG7PlwkcDt8VzQYYl87MBtDpPmdYkWYPnS+5XAoGBANrz +uSjbbTEX4a3WGsot9WzyhML11WgsdMgbqSWLMEmj2guwm4jn3XdqA+6nZAUJHgPI +Ir5l2E3zWTdw5pZ0+IkQnj/OJP2OLqS+msVMl89PHJjtPyB2LVjCg+Z/vfm2ar5S +RnQ/AoR5cSXctiL9wJbJBidfZeEpXBSeKN/SW6/BAoGAXaQ4EXpWq4wQyAzRT9xG +HP0G1wU30BLolp2vW5Vqdwb+Wuoic+OGGqmJk/T4Uhlb47gCIjcopg0D6d4tcXUl +3Pcejf5+w950JUfmHeYXGJBvRYR4qXxdFkYJlZqpF+4Gyei4o7v51Astp/KGFLza +YDV3l25t9NPJxIEG16XQM28CgYEAyT3yFYd42QKmPuznOqT7SuOs+rSRLWqO+83Q +rd08yLJ9Gvl8O11BxRv/+T6JQ8eZeshchrt9EEh22+o9RlTEitZnXSXQAezJGkrG +XkmDzttb4YNN3jxAebBvI1COABKWEc/1SasQWUp1oOM31Pl+JhkmOtIIBefJ5nlo +ADCMbQECgYBdpg/2J58JOB0NhFFUDh3+6+bzZIciT7BYZ8zYBej5DR6kd4Inkvvl +JxOlYIKSew5uyi7i2po7fBFRhKuyfpNMBYK01ObrgJNZELbqVgYvKw1HEqqtgExa +eMVHHbWm1CpGO294R+vMBv4jcuhIBOx63KZE4VaoJuaazF6TE5czDw== +-----END RSA PRIVATE KEY----- +""" + + +#: CN=san.example.org, issued by LemurTrust Unittests Class 1 CA 2018 +SAN_CERT_STR = """\ +-----BEGIN CERTIFICATE----- +MIIESjCCAzKgAwIBAgIRAK/y20+NLU2OgPo4KuJ8IzMwDQYJKoZIhvcNAQELBQAw +gacxLTArBgNVBAMMJExlbXVyVHJ1c3QgVW5pdHRlc3RzIENsYXNzIDEgQ0EgMjAx +ODEjMCEGA1UECgwaTGVtdXJUcnVzdCBFbnRlcnByaXNlcyBMdGQxJjAkBgNVBAsM +HVVuaXR0ZXN0aW5nIE9wZXJhdGlvbnMgQ2VudGVyMQswCQYDVQQGEwJFRTEMMAoG +A1UECAwDTi9BMQ4wDAYDVQQHDAVFYXJ0aDAeFw0xNzEyMzEyMjAwMDBaFw00NzEy +MzEyMjAwMDBaMHgxGDAWBgNVBAMMD3Nhbi5leGFtcGxlLm9yZzEYMBYGA1UECgwP +RGFuaWVsIFNhbiAmIGNvMRcwFQYDVQQLDA5LYXJhdGUgTGVzc29uczELMAkGA1UE +BhMCRUUxDDAKBgNVBAgMA04vQTEOMAwGA1UEBwwFRWFydGgwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDImvQXKcqWVFPcSaJJ83RKfgHr0BPd10gMpSJV +44vNGZWEv0/5lVrbuoTcM9iCQwRYepz2h09VHfwCOGGpwzGvnxeCicc5ZCj22Krl +seBDo02drBQQQor8MZaNUqPK+R3+DWfRMLuACJmt85pPnc8SU6Z1m0yBSRrAxi8C +TvYrurqn+/VXWJBhCwrrKt3chdo9gzQ4hh6EXEGBTDIQykermJgk2L8I39PrH+pN +c5NhCtV/mVlMoz/jZdjQem6S9E8nRe+X7qZVkTnM3HojugSjuGE9rjT3ReAQB6f5 +EApKp48ORQl+zzjUU+ME1vwIw5LeVjoGPgAfdM0AT8b11m1DAgMBAAGjgZ4wgZsw +DAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMC +BaAwHQYDVR0OBBYEFPMfkyOR6taOKARGUn1zyauOeOhAMEcGA1UdEQEB/wQ9MDuC +D3Nhbi5leGFtcGxlLm9yZ4IQc2FuMi5leGFtcGxlLm9yZ4IWZGFuaWVsLXNhbi5l +eGFtcGxlLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAJer6tDWlcc4gDvZEbPNpFPKY +kPqww6WtVKrsyPQyucmP7arFx+kUulkZN6GY6FyIao7zQPrHU3GqtPXt/lR++wzz +bnj+iHONNoAY5TZLycPXAW7pn8UCvdQzkyhMzCB1aRkRS/Tr0/sC0T5lYux42dQG +rTUxVG7Umr4jq8hKEElNIwxF+3kkfzztICZXJtzmVRAz4XpmXmyMcZOOXh3F7z04 +kePn3ztNEJNuGK0qMnTJlL7T2a9v+Q29YhIiNqCFdoALJbzJmEj3+QgcLFJh3KjY +J4WEmpGK7FylxmZLrya12SxPMA8A60hMPeWH90xRS8SJfd57K5oCluGK14X+og== +-----END CERTIFICATE----- +""" +SAN_CERT = parse_certificate(SAN_CERT_STR) +SAN_CERT_KEY = """\ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAyJr0FynKllRT3EmiSfN0Sn4B69AT3ddIDKUiVeOLzRmVhL9P ++ZVa27qE3DPYgkMEWHqc9odPVR38AjhhqcMxr58XgonHOWQo9tiq5bHgQ6NNnawU +EEKK/DGWjVKjyvkd/g1n0TC7gAiZrfOaT53PElOmdZtMgUkawMYvAk72K7q6p/v1 +V1iQYQsK6yrd3IXaPYM0OIYehFxBgUwyEMpHq5iYJNi/CN/T6x/qTXOTYQrVf5lZ +TKM/42XY0HpukvRPJ0Xvl+6mVZE5zNx6I7oEo7hhPa4090XgEAen+RAKSqePDkUJ +fs841FPjBNb8CMOS3lY6Bj4AH3TNAE/G9dZtQwIDAQABAoIBAQCxN3J7JAg8VbLf +4IzmF5ScWkUINYHXcN/Ni/SRO7u9LOTRqNDWBAOIKXZFseeK6/li0K7pew+yehKv +Q2/DsRSruTfjsiO1p64oo7AVytX76sAekm4HD0IJGSWPI3pfTUQZs24Ld6msqexZ +p+Kigx7zacKcEt27OQHRW0McHvWKGpCzc+G9o8hlYumtnTnR8kP4bYG4MpCVtZdt +ZuQr9QHEH7omQzWedLHICqGLP8WBu+lMY3bPM/gLgBSy2f8CP5MBy7xUUSTgolCc +ZZIt2H2cCStfb3y61WvDHX/bZ7B/a0lDWKHUK2f9Du5ENOWAAsaIUCPGrFwMFM1n +ANPtYIUBAoGBAP7SXzTcsHx0Iy1TMqluQxZNL7Up6dHksZFEO8zAwmg6Z3VHsXjc +3ovst1gQRWUzEhc2Soun8KbZ4ZVhApHpkxg+lLio2A4mLm7xf6ASsPwkwUCwUBYP +zSt56oopQ6BIc84ZDNe5QZY9OziRyHRc0SgVhuoK1i2t832kUii/aWmTAoGBAMmI +aA6vDlojHnyhvNCS/v+aOEjNyW7LJjDhNK6qTKZF7FeCSjTLxzJJ6XddQjLXnjVa +aF1I0dYPLQfjbeDaM6pKyg4l0pnN70qh9YgFCCIxU0dIqL2v0a057JILwlC4ZU8z +rmQEP3DROGGi50r74/SoYMBVm6r/6opYkThF+HuRAoGBAIHxrXM7hxQv9TBL2O3l +uHhK7CUqNn4+bP5zGTuUoI6eGdwIr0u+9g3MrMJPqdOtc3A601DcVy/+s7aFPdZC +kiwu3ZA9KdAtUEhrBnYOkgpCg/oE7xIRBMNC7IN//2hhCgzzYUUwx21h1C1Iyjvs +iQwzzhTTadzpc92CShNVaN/ZAoGBAKwG+fv+xdt/OtjcHpZTw8NfW0gaESW31yPG +OPgXelI8QZ/5IWqrv59XpCg1vPo1P2D/iTKHpEZ6sc+X/QUAfTWRnaQx+PE87lPg +p/uxf93gCNxCU3eHiw248g1AaGAK5r+St/u7/INKtDvzmEdTeKQwzlWfPb/br9Lk +AyHr6E1hAoGAN375PaykO+webBV9GkUwCcs1wTmDFjWKuaCVk9qvj8qavr1HOarb +ZolDBFYQSUUcOJHE9QRg7zDWTjI+Av670rXtTsREs0yMkdHhF/aRD7FJoBvO/7v/ +tqdgqMHlJ0YPL/8/6sTMasepIqmAkQgFINzDskHubBBEPfHKqF0KQA4= +-----END RSA PRIVATE KEY----- +""" + +WILDCARD_CERT_STR = """\ +-----BEGIN CERTIFICATE----- +MIIEJDCCAwygAwIBAgIPK/QvcZhAY7VPU7Ek/nCDMA0GCSqGSIb3DQEBCwUAMIGn +MS0wKwYDVQQDDCRMZW11clRydXN0IFVuaXR0ZXN0cyBDbGFzcyAxIENBIDIwMTgx +IzAhBgNVBAoMGkxlbXVyVHJ1c3QgRW50ZXJwcmlzZXMgTHRkMSYwJAYDVQQLDB1V +bml0dGVzdGluZyBPcGVyYXRpb25zIENlbnRlcjELMAkGA1UEBhMCRUUxDDAKBgNV +BAgMA04vQTEOMAwGA1UEBwwFRWFydGgwHhcNMTcxMjMxMjIwMDAwWhcNNDcxMjMx +MjIwMDAwWjB9MRswGQYDVQQDDBIqLndpbGQuZXhhbXBsZS5vcmcxETAPBgNVBAoM +CFBsYXl0ZWNoMRkwFwYDVQQLDBBJbmZyYSBPcGVyYXRpb25zMQswCQYDVQQGEwJF +RTERMA8GA1UECAwISGFyanVtYWExEDAOBgNVBAcMB1RhbGxpbm4wggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCoT8Ak5kynUzosBvP8hCnP4hGMAtgHLcHG +UBWug4BofAhxxBrZW3UteoQzNznK5jz0hy2azqnz3/9q5N/FKwHxfMY/VEHPXyYK +QsZuSdVceJ/EHL+MLx+uisIRJstV8fC5oYRfg74m07ZED7NM4EerJTxKZAy7UuSM +L65i/LEChPzjLN46GcUEuC2O03nZtFTPvN9j7vzen9/qIzs1TGQukOn4z5l2GuAx +RCEfBl3IrnvSY+npGARPJsXSymXCCP3ntzq6I6iRHuZf+QETZtiMR1TCNZRTqcc2 +LxWn+W5N18yyXvUcVMfrg4jzEWKHuhwInoiH1pu/myyKrnoIi4nTAgMBAAGjdjB0 +MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8E +AjAAMB0GA1UdDgQWBBRR9Q9DHJRPt69Qm8lir4iJfOmJ4TAgBgNVHREBAf8EFjAU +ghIqLndpbGQuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQELBQADggEBAMm2DiYfGLve +r/gCtYgXKkRmbuv57PmAUm52w5l4hjxssdUwq4Wn4T+K0+Sqp3IzcNhEaIqPB+bG +8rIbJLBiiDPbSUZC0DbvlXihk7FHjqmrbVFwNmkWNywLhB1qOlp0kQH+w9lDWA1p +y99P0Bxcot66scbiaag0i0AUpkRKbUG+v+VGXdPrJrWE+63ROhWQMmQNiUlZ6QGO +45tUSn//MuUpJiJVkUVR1fSbCpHQj2mHiuhShOmatmh5e1ISwVP19cX64Gr6djlY +wKJqcmw7WDjl+T+y7luJWw4UqI7s7hY6Y9RQVh61L4eV8CIma3NmTaQCSgR3tCxh +d4FCKAE8+Lw= +-----END CERTIFICATE----- +""" +WILDCARD_CERT = parse_certificate(WILDCARD_CERT_STR) +WILDCARD_CERT_KEY = """\ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAqE/AJOZMp1M6LAbz/IQpz+IRjALYBy3BxlAVroOAaHwIccQa +2Vt1LXqEMzc5yuY89Ictms6p89//auTfxSsB8XzGP1RBz18mCkLGbknVXHifxBy/ +jC8frorCESbLVfHwuaGEX4O+JtO2RA+zTOBHqyU8SmQMu1LkjC+uYvyxAoT84yze +OhnFBLgtjtN52bRUz7zfY+783p/f6iM7NUxkLpDp+M+ZdhrgMUQhHwZdyK570mPp +6RgETybF0splwgj957c6uiOokR7mX/kBE2bYjEdUwjWUU6nHNi8Vp/luTdfMsl71 +HFTH64OI8xFih7ocCJ6Ih9abv5ssiq56CIuJ0wIDAQABAoIBAHpE3SexKbRQMK01 +K9+gPyOmberRUg/8/IzNNsL9ArZkjFnhBUQrPXeZThpKnzA3i8ZzwPx571qbudf0 +hl6cfJ/qbbYpxlkYHPFNSwtplZbEhgOYgsoanaBVat+81/AKfz7LB/e/I87e88SD +x1QshcPdm+vKvLkEYcU5Ci0ctpZFyjgqWAVdsaEmstSpygOsU/CExiiq20MuGXQV +lfRpYqmA0D1LicN6t0rGRNLUHWzhZS5s1ZHD8oR5bgtlcxvOSDm81ROfV1obAQRo +RyCeYG9Juo2BisyuG5RsKuzfWvP6goxXdGD2uTOj7rdMYRfnUzsz4QXkzdA+IEE9 +qmv9gsECgYEA0gYoSVwF+koYL8SURMLbQPdmVBiTSxZQytSaFTl9WWYUvyFJ/R0c +xmuMjfVvnxuMUa6qHcaOt9Gjq0pAp2T10/8B+fB8XAJ0bxl6DKArxIONx7W1T8RX +SdEAWF77eRlSPAD4dfAyFIjPzCH4l98nX84sRk+GiusLGhm5MdwTS2ECgYEAzSgB +H33YIfPMW7Mh9R7QpfQRyda9Ikb8pGDegprTLp9SDLU0zCZ3aPmSN3iVrGThwcf1 +olnx5g8ZK9qiLLIUctxJWeK/EO2HAii/fmasJfq4zI0xBflkX25V+BbZRqU8GDa0 +dLpOcr1cIEFAqpZ182O1uXAJdGzkVv4LN5Iq9bMCgYBuYAIIG66gjRQM9pidUnJ7 +wAktJQUzrvSiw/x+LwprUzSQBeSmewhGVvs1F8mjqoyh2NNadqFGhYwoVwuHbY2r +7haRzgrtJ/Uc9hyoSfz2d9SpIhu5YgwlpQszZiduyxnmovPwt1z6YbQjKa9F0WcV ++HpYMS8aDtB01RP42hnhwQKBgHDg8PU9zZyowqk1v5pZ8R1OVDdE4t2oRzu+XM9p +loaRfJinXzxwccUdhFjnDRtEin6PodRJPvKBHi1l51NGTEACeo1tWAldV6pVdz96 +CIABGorZqL6LwLFNSRnuoG/hXFZKSzHqjF1PWRAaNxVlIdLf6s30Gg+oFl7S+qMB +1odHAoGAQqPWDTSBVhbMIzXXoGGjIx08WG9xuNqRyQ6fjekSporXisoej1XB+pYA +wZF7+p71qUsrVrg+j7SRm8pFsR79nvshQImzaLGOCLUsdHZfcKjfy8D7wB6T7AmF +gt+hqNmTFkpLkvaze7sBEwRWRU0/RWpZLDmx3+zvRXPw1lQmB1Q= +-----END RSA PRIVATE KEY----- +""" + + +INVALID_CERT_STR = """ -----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgICA+gwDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAlVT MQswCQYDVQQIDAJDQTEQMA4GA1UEBwwHQSBwbGFjZTEXMBUGA1UEAwwObG9uZy5s @@ -72,66 +279,7 @@ T7W3s8mm5bVHhQM7J9tV6dz/sVDmpOSuzL8oZkqeKP+lWU6ytaohFFpbdzaxWipU kP+oGWtHvhteUAe8Gloo5NchZJ0/BqlYRCD5aAHcmbXRsDid9mO4ADU= -----END CERTIFICATE----- """ -INTERNAL_INVALID_CERT = parse_certificate(INTERNAL_INVALID_STR) - - -INTERNAL_VALID_SAN_STR = """ ------BEGIN CERTIFICATE----- -MIIESjCCAzKgAwIBAgICA+kwDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAlVT -MQswCQYDVQQIDAJDQTEQMA4GA1UEBwwHQSBwbGFjZTEXMBUGA1UEAwwObG9uZy5s -aXZlZC5jb20xEDAOBgNVBAoMB0V4YW1wbGUxEzARBgNVBAsMCk9wZXJhdGlvbnMx -HjAcBgkqhkiG9w0BCQEWD2ppbUBleGFtcGxlLmNvbTAeFw0xNTA2MjYyMDU5MDZa -Fw0yMDAxMDEyMDU5MDZaMG0xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4G -A1UEBxMHQSBwbGFjZTEQMA4GA1UEChMHRXhhbXBsZTETMBEGA1UECxMKT3BlcmF0 -aW9uczEYMBYGA1UEAxMPc2FuLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA2Nq5zFh2WiqtNIPssdSwQ9/00j370VcKPlOATLqK24Q+ -dr2hWP1WlZJ0NOoPefhoIysccs2tRivosTpViRAzNJXigBHhxe8ger0QhVW6AXIp -ov327N689TgY4GzRrwqavjz8cqussIcnEUr4NLLsU5AvXE7e3WxYkkskzO497UOI -uCBtWdCXZ4cAGhtVkkA5uQHfPsLmgRVoUmdMDt5ZmA8HhLX4X6vkT3oGIhdGCw6T -W+Cu7PfYlSaggSBbBniU0YKTFLfGLkYFZN/b6bxzvt6CTJLoVFAYXyLJwUvd3EAm -u23HgUflIyZNG3xVPml/lah0OIX7RtSigXUSLm7lYwIDAQABo4HTMIHQMAwGA1Ud -EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMB -MC8GA1UdEQQoMCaCEWV4YW1wbGUyLmxvbmcuY29tghFleGFtcGxlMy5sb25nLmNv -bTAdBgNVHQ4EFgQUiiIyclcBIfJ5PE3OCcTXwzJAM+0wSAYDVR0fBEEwPzA9oDug -OYY3aHR0cDovL3Rlc3QuY2xvdWRjYS5jcmwubmV0ZmxpeC5jb20vbG9uZ2xpdmVk -Q0EvY3JsLnBlbTANBgkqhkiG9w0BAQsFAAOCAQEAgcTioq70B/aPWovNTy+84wLw -VX1q6bCdH3FJwAv2rc28CHp5mCGdR6JqfT/H/CbfRwT1Yh/5i7T5kEVyz+Dp3+p+ -AJ2xauHrTvWn0QHQYbUWICwkuZ7VTI9nd0Fry1FQI1EeKiCmyrzNljiN2l+GZw6i -NJUpVNtwRyWRzB+yIx2E9wyydqDFH+sROuQok7EgzlQileitPrF4RrkfIhQp2/ki -YBrY/duF15YpoMKAlFhDBh6R9/nb5kI2n3pY6I5h6LEYfLStazXbIu61M8zu9TM/ -+t5Oz6rmcjohL22+sEmmRz86dQZlrBBUxX0kCQj6OAFB4awtRd4fKtkCkZhvhQ== ------END CERTIFICATE----- -""" -INTERNAL_VALID_SAN_CERT = parse_certificate(INTERNAL_VALID_SAN_STR) - - -INTERNAL_VALID_WILDCARD_STR = """ ------BEGIN CERTIFICATE----- -MIIEHDCCAwSgAwIBAgICA+owDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAlVT -MQswCQYDVQQIDAJDQTEQMA4GA1UEBwwHQSBwbGFjZTEXMBUGA1UEAwwObG9uZy5s -aXZlZC5jb20xEDAOBgNVBAoMB0V4YW1wbGUxEzARBgNVBAsMCk9wZXJhdGlvbnMx -HjAcBgkqhkiG9w0BCQEWD2ppbUBleGFtcGxlLmNvbTAeFw0xNTA2MjYyMTEzMTBa -Fw0yMDAxMDEyMTEzMTBaMHAxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4G -A1UEBxMHQSBwbGFjZTEQMA4GA1UEChMHRXhhbXBsZTETMBEGA1UECxMKT3BlcmF0 -aW9uczEbMBkGA1UEAxQSKi50ZXN0LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA0T7OEY9FxMIdhe1CwLc+TbDeSfDN6KRHlp0I9MwK -3Pre7A1+1vmRzLiS5qAdOh3Oexelmgdkn/fZUFI+IqEVJwmeUiq13Kib3BFnVtbB -N1RdT7rZF24Bqwygf1DHAekEBYdvu4dGD/gYKsLYsSMD7g6glUuhTbgR871updcV -USYJ801y640CcHjai8UCLxpqtkP/Alob+/KDczUHbhdxYgmH34aQgxC8zg+uzuq6 -bIqUAc6SctI+6ArXOqri7wSMgZUnogpF4R5QbCnlDfSzNcNxJFtGp8cy7CNWebMd -IWgBYwee8i8S6Q90B2QUFD9EGG2pEZldpudTxWUpq0tWmwIDAQABo4GiMIGfMAwG -A1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBYGA1UdJQEB/wQMMAoGCCsGAQUF -BwMBMB0GA1UdDgQWBBTH2KIECrqPHMbsVysGv7ggkYYZGDBIBgNVHR8EQTA/MD2g -O6A5hjdodHRwOi8vdGVzdC5jbG91ZGNhLmNybC5uZXRmbGl4LmNvbS9sb25nbGl2 -ZWRDQS9jcmwucGVtMA0GCSqGSIb3DQEBCwUAA4IBAQBjjfur2B6BcdIQIouwhXGk -IFE5gUYMK5S8Crf/lpMxwHdWK8QM1BpJu9gIo6VoM8uFVa8qlY8LN0SyNyWw+qU5 -Jc8X/qCeeJwXEyXY3dIYRT/1aj7FCc7EFn1j6pcHPD6/0M2z0Zmj+1rWNBJdcYor -pCy27OgRoJKZ6YhEYekzwIPeFPL6irIN9xKPnfH0b2cnYa/g56DyGmyKH2Kkhz0A -UGniiUh4bAUuppbtSIvUTsRsJuPYOqHC3h8791JZ/3Sr5uB7QbCdz9K14c9zi6Z1 -S0Xb3ZauZJQI7OdHeUPDRVq+8hcG77sopN9pEYrIH08oxvLX2US3GqrowjOxthRa ------END CERTIFICATE----- -""" -INTERNAL_VALID_WILDCARD_CERT = parse_certificate(INTERNAL_VALID_WILDCARD_STR) +INVALID_CERT = parse_certificate(INVALID_CERT_STR) EXTERNAL_VALID_STR = """ @@ -169,36 +317,6 @@ Bs63gULVCqWygt5KEbv990m/XGuRMaXuHzHCHB4v5LRM30FiFmqCzyD8d+btzW9B EXTERNAL_CERT = parse_certificate(EXTERNAL_VALID_STR) -PRIVATE_KEY_STR = """ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAnEjM0cQevlDjT6mDMtTo8N1ovAyKbfVEp0ketCPC4hLkStms -q9ETIyyerARIMv4SEhKqS4E7HIg6ccGkwv1ja5E/b2jHMH4ht1dEXnfM2yh0Mwvk -8nC0YPcGwt7+td5GiGQkAqBOwKLq7vVm1T5rkaGrH87a4JLFph/Yp30Gy+Ew3JnM -aKhmjJ+Go0E1QA+twip7rfglC2SDAURAVZUky4jju6mXU63fr47S1r3V1T3Fi0ga -3Vabt2J4aqk7XvgzM0B8GOwNrN37uAoOB+J6c3EftB9R/wec+uJMamavRVhiHGXM -+9MV3hzfVFCjw0k4LI7SMyk2iDnvXjC94xklOwIDAQABAoIBAGeykly5MeD70OgB -xPEMfoebkav88jklnekVxk6mz9+rw1i6+CyFLJqRN7NRoApdtOXTBrXUyMEUzxq9 -7zIGaVptZNbqggh2GK8LM20vNnlQbVGVmdMX30fbgNv6lK1eEBTdxVsMvVRqhVIK -+LGTmlJmICKZ4XdTS9v/k4UGm2TZPCt2pvrNzIpT7TIm2QybCbZoOPY8SHx0U8c5 -lmtdqmIsy2JPNSOsOCiJgzQIvkR/fMGWFgNE4fEHsHAfubgpK97TGzwLiFRmlTb+ -QUDaz0YbwhF+5bQjHtaGUGATcg5bvV1UWBUvp+g4gRIfwzG+3PAGacYE/djouAdG -PHbxuCkCgYEAz/LsgMgsaV3arlounviSwc8wG9WcI5gbYw5qwX0P57ZoxS7EBAGu -yYtudurJrU9SfsSV44GL11UzBcAGOeS0btddrcMiNBhc7fY7P/1xaufQ3GjG06/v -kH4gOjzsGSTJliZ709g4J6hnMCxz0O0PS31Qg5cBD8UG8xO7/AV0is0CgYEAwGWy -A6YPinpZuenaxrivM5AcVDWmj7aeC29M63l/GY+O5LQH2PKVESH0vL5PvG3LkrCR -SUbaMKdKR0wnZsJ89z21eZ54ydUgj41bZJczl8drxcY0GSajj6XZXGTUjtoVrWsB -A0kJbjsrpd+8J316Y9iCgpopmbVd965pUHe4ACcCgYAamJlDB1cWytgzQHmB/4zV -mOgwRyvHKacnDir9QD+OhTf1MDwFvylZwamJMBJHRkPozr/U7zaxfcYe0CZ7tRKW -spjapoBzZUJNdRay4nllEO0Xo5b6cCAVvOvmRvBzbs8Rky53M8pK2DEKakUNzaQN -JaPskJ2kJLD02etLGm+DaQKBgQCTI/NNmQ2foUzHw1J+0jWjoJ4ZxOI6XLZoFlnk -aInMuZ7Vx92MjJF2hdqPEpkWiX28FO839EjgFsDW4CXuD+XUjEwi1BCagzWgs8Hm -n0Bk3q3MlnW3mnZSYMtoPvDUw3L6qrAenBfrRrNt6zsRlIQqoiXFzjLsi+luh+Oh -F74P1wKBgQCPQGKLUcfAvjIcZp4ECH0K8sBEmoEf8pceuALZ3H5vneYDzqMDIceo -t5Gpocpt77LJnNiszXSerj/KjX2MflY5xUXeekWowLVTBOK5+CZ8+XBIgBt1hIG3 -XKxcRgm/Va4QMEAnec0qXfdTVJaJiAW0bdKwKRRrrbwcTdNRGibdng== ------END RSA PRIVATE KEY----- -""" - INTERNAL_CERTIFICATE_A_STR = """ -----BEGIN CERTIFICATE----- MIIDazCCAlOgAwIBAgIBATANBgkqhkiG9w0BAQsFADB5MQswCQYDVQQGEwJVUzET