mcp-security-framework 1.1.2__py3-none-any.whl → 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_security_framework/__init__.py +1 -1
- mcp_security_framework/cli/cert_cli.py +167 -3
- mcp_security_framework/core/auth_manager.py +32 -10
- mcp_security_framework/core/cert_manager.py +261 -6
- mcp_security_framework/core/ssl_manager.py +41 -9
- mcp_security_framework/middleware/mtls_middleware.py +10 -2
- mcp_security_framework/schemas/config.py +31 -0
- mcp_security_framework/schemas/models.py +46 -0
- mcp_security_framework/utils/cert_utils.py +309 -8
- {mcp_security_framework-1.1.2.dist-info → mcp_security_framework-1.2.1.dist-info}/METADATA +1 -1
- {mcp_security_framework-1.1.2.dist-info → mcp_security_framework-1.2.1.dist-info}/RECORD +17 -16
- tests/test_core/test_auth_manager.py +6 -6
- tests/test_utils/test_cert_utils.py +168 -0
- tests/test_utils/test_unitid_compat.py +550 -0
- {mcp_security_framework-1.1.2.dist-info → mcp_security_framework-1.2.1.dist-info}/WHEEL +0 -0
- {mcp_security_framework-1.1.2.dist-info → mcp_security_framework-1.2.1.dist-info}/entry_points.txt +0 -0
- {mcp_security_framework-1.1.2.dist-info → mcp_security_framework-1.2.1.dist-info}/top_level.txt +0 -0
@@ -1,15 +1,15 @@
|
|
1
|
-
mcp_security_framework/__init__.py,sha256=
|
1
|
+
mcp_security_framework/__init__.py,sha256=wRlT28hRsnSZCUVNGtU-KggRk66KzSQl4agKOxE5ZCA,3172
|
2
2
|
mcp_security_framework/constants.py,sha256=k7NMSrgc83Cci8aoilybQxdC7jir7J-mVFE_EpqVrDk,5307
|
3
3
|
mcp_security_framework/cli/__init__.py,sha256=plpWdiWMp2dcLvUuGwXynRg5CDjz8YKnNTBn7lcta08,369
|
4
|
-
mcp_security_framework/cli/cert_cli.py,sha256=
|
4
|
+
mcp_security_framework/cli/cert_cli.py,sha256=LdZ3SYKM3e3dP5LsVR5Y0OENtlG0ENu64aHefHjuiN8,23818
|
5
5
|
mcp_security_framework/cli/security_cli.py,sha256=Thine_Zzfesz7j29y2k_XZFYUK5YSrhCc6w2FilgEiE,28486
|
6
6
|
mcp_security_framework/core/__init__.py,sha256=LiX8_M5qWiTXccJFjSLxup9emhklp-poq57SvznsKEg,1729
|
7
|
-
mcp_security_framework/core/auth_manager.py,sha256=
|
8
|
-
mcp_security_framework/core/cert_manager.py,sha256=
|
7
|
+
mcp_security_framework/core/auth_manager.py,sha256=GqGAW83Qg1_z2HJ0-FEVTmlli_DBSOPOap2jJMEU1_k,39882
|
8
|
+
mcp_security_framework/core/cert_manager.py,sha256=RJgZxElPgMV15Lj_N2uCyO7Ofb9z-MclM1hf8wzFwSc,88882
|
9
9
|
mcp_security_framework/core/permission_manager.py,sha256=SADS_oXpwp9MhXHKJMCsvjEq8KWcz7vPYL05Yr-zfio,26478
|
10
10
|
mcp_security_framework/core/rate_limiter.py,sha256=6qjVBxK2YHouSxQuCcbr0PBpRqA5toQss_Ce178RElY,20682
|
11
11
|
mcp_security_framework/core/security_manager.py,sha256=mAF-5znqxin-MSSgXISB7t1kTkqHltEqGzzmlLAhRGs,37766
|
12
|
-
mcp_security_framework/core/ssl_manager.py,sha256=
|
12
|
+
mcp_security_framework/core/ssl_manager.py,sha256=SXuN5PMTAnMNz04CEKzHbxRKjzF-VqvS-QCFhV-wFeo,29133
|
13
13
|
mcp_security_framework/examples/__init__.py,sha256=nfYPVvIQ5wHuDkQvyCYDd1VjCsZMw9HnvjeUORqKyuQ,1915
|
14
14
|
mcp_security_framework/examples/comprehensive_example.py,sha256=6CXkqLFjWIQ2rRMYPnDrBdBuWFKbeu2gd2GI_SFVjds,35421
|
15
15
|
mcp_security_framework/examples/django_example.py,sha256=IHk-aHsah-cEHjvsngUx91lup1aRC8W9XHzK6jfOMdA,24628
|
@@ -25,16 +25,16 @@ mcp_security_framework/middleware/fastapi_auth_middleware.py,sha256=LWVEn90I1XpV
|
|
25
25
|
mcp_security_framework/middleware/fastapi_middleware.py,sha256=Ye0qJsEMwgeUqVJpqXgbjJJbbf-ZU-6SysMQPmQba-s,26658
|
26
26
|
mcp_security_framework/middleware/flask_auth_middleware.py,sha256=ubBlKO0ponOV_KuxkUK4xGcSoslXTaikrdsIZQtGeV0,20228
|
27
27
|
mcp_security_framework/middleware/flask_middleware.py,sha256=Ag0zYDKwlvU78LBQ-7Za14IYOAlEVZaXJPD0Qc4MUvA,20666
|
28
|
-
mcp_security_framework/middleware/mtls_middleware.py,sha256=
|
28
|
+
mcp_security_framework/middleware/mtls_middleware.py,sha256=WSyWIk1fCN96hkofODKj_kzLG0d7A0NmDnTr3HHZ5xw,14213
|
29
29
|
mcp_security_framework/middleware/rate_limit_middleware.py,sha256=deCwwigI0Pt7pBUnk2jDurI9ZyjujWTsexEWWndXm3g,13177
|
30
30
|
mcp_security_framework/middleware/security_middleware.py,sha256=PQ251Fr2UrYVPgGfhXq6QJyqK2tRk0WCIg9_FBvfVkg,16844
|
31
31
|
mcp_security_framework/schemas/__init__.py,sha256=lefkbRlbj2ICfasSj51MQ04o3z1YycnbnknSJCFfXbU,2590
|
32
|
-
mcp_security_framework/schemas/config.py,sha256=
|
33
|
-
mcp_security_framework/schemas/models.py,sha256=
|
32
|
+
mcp_security_framework/schemas/config.py,sha256=SUUrpOz9ZTIhZG9Fu2Gsz86yxoGbUt00Qk-Qk_GaTus,26819
|
33
|
+
mcp_security_framework/schemas/models.py,sha256=Izjy3I55zjMVLsVZpXZ0M4aK3SCks9sC2U1cbxrXYeI,28439
|
34
34
|
mcp_security_framework/schemas/responses.py,sha256=nVXaqF5GTSprXTa_wiUEu38nvSw9WAXtKViAJNbO-Xg,23206
|
35
35
|
mcp_security_framework/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
36
|
mcp_security_framework/utils/__init__.py,sha256=wwwdmQYHTSz0Puvs9FD6aIKmWp3NFARe3JPWNH-b_wk,3098
|
37
|
-
mcp_security_framework/utils/cert_utils.py,sha256=
|
37
|
+
mcp_security_framework/utils/cert_utils.py,sha256=4AHNrfL0Oqp354aEq5H2_0XLT7v3mNOnTVDV-DLaJyI,27585
|
38
38
|
mcp_security_framework/utils/crypto_utils.py,sha256=OH2V7_C3FjStxFTIXMUPfNXZuWG2-QjgoBrIH4Lv4p0,12392
|
39
39
|
mcp_security_framework/utils/datetime_compat.py,sha256=ool-xs-EevhuYygdzhiAenLAacLuZwGwjPkF43i-9gg,3859
|
40
40
|
mcp_security_framework/utils/validation_utils.py,sha256=e9BX3kw9gdXSmFsc7lmG-qnzSlK0-Ynn7Xs4uKHquF4,16279
|
@@ -44,7 +44,7 @@ tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
44
|
tests/test_cli/test_cert_cli.py,sha256=Rm7z-20VAvnmYKY3sgxS-qVNks1vbniQJSpSxjsx_wo,14677
|
45
45
|
tests/test_cli/test_security_cli.py,sha256=Bpd31IPJSUl_V1Xzy74ZCOvQpwlbj8Da83C46T8Jewg,25569
|
46
46
|
tests/test_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
|
-
tests/test_core/test_auth_manager.py,sha256=
|
47
|
+
tests/test_core/test_auth_manager.py,sha256=7Z2DLfJLqKtiwX5Q-lR85hN6NxHbE2Q_FT7IsoyKPQk,22568
|
48
48
|
tests/test_core/test_cert_manager.py,sha256=4YMAkRedkAZW3PEZYEbo1PyrzMntUrKfl7arPsHXDCE,36356
|
49
49
|
tests/test_core/test_permission_manager.py,sha256=0XeghWXZqVpKyyRuhuDu1dkLUSwuZaFWkRQxQhkkFVI,14966
|
50
50
|
tests/test_core/test_rate_limiter.py,sha256=YzzlhlxZm-A7YGMiIV8LXDA0zmb_6uRF9GRx9s21Q0U,22544
|
@@ -73,12 +73,13 @@ tests/test_schemas/test_models.py,sha256=bBeZOPqveuVJuEi_BTVWdVsdj08JXJTEFwvBM4e
|
|
73
73
|
tests/test_schemas/test_responses.py,sha256=ZSbO7A3ThPBovTXO8PFF-2ONWAjJx2dMOoV2lQIfd8s,40774
|
74
74
|
tests/test_schemas/test_serialization.py,sha256=jCugAyrdD6Mw1U7Kxni9oTukarZmMMl6KUcl6cq_NTk,18599
|
75
75
|
tests/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
76
|
-
tests/test_utils/test_cert_utils.py,sha256=
|
76
|
+
tests/test_utils/test_cert_utils.py,sha256=yZGHPuJcjgSHFeT7gnMdsw6UYXmlGUiuHkErukOm8II,28238
|
77
77
|
tests/test_utils/test_crypto_utils.py,sha256=yEb4hzG6-irj2DPoXY0DUboJfbeR87ussgTuBpxLGz4,20737
|
78
78
|
tests/test_utils/test_datetime_compat.py,sha256=n8S4X5HN-_ejSNpgymDXRyZkmxhnyxwwjxFPdX23I40,5656
|
79
|
+
tests/test_utils/test_unitid_compat.py,sha256=MWh03A4FwzQyZa20PKHEWz4W03YtARwBOd_1JbABznQ,25544
|
79
80
|
tests/test_utils/test_validation_utils.py,sha256=lus_wHJ2WyVnBGQ28S7dSv78uWcCIuLhn5uflJw-uGw,18569
|
80
|
-
mcp_security_framework-1.1.
|
81
|
-
mcp_security_framework-1.1.
|
82
|
-
mcp_security_framework-1.1.
|
83
|
-
mcp_security_framework-1.1.
|
84
|
-
mcp_security_framework-1.1.
|
81
|
+
mcp_security_framework-1.2.1.dist-info/METADATA,sha256=3HiQhhOc1aqdstjAhfUnT2gRmxg61pYutP_lVkn6cxw,11771
|
82
|
+
mcp_security_framework-1.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
83
|
+
mcp_security_framework-1.2.1.dist-info/entry_points.txt,sha256=qBh92fVDmd1m2f3xeW0hTu3Ksg8QfGJyV8UEkdA2itg,142
|
84
|
+
mcp_security_framework-1.2.1.dist-info/top_level.txt,sha256=ifUiGrTDcD574MXSOoAN2rp2wpUvWlb4jD9LTUgDWCA,29
|
85
|
+
mcp_security_framework-1.2.1.dist-info/RECORD,,
|
@@ -46,7 +46,7 @@ class TestAuthManager:
|
|
46
46
|
|
47
47
|
# Create test configuration
|
48
48
|
self.auth_config = AuthConfig(
|
49
|
-
api_keys={"
|
49
|
+
api_keys={"test_user": "test_api_key_123"},
|
50
50
|
jwt_secret="test_jwt_secret_key_32_chars_long",
|
51
51
|
jwt_expiry_hours=1,
|
52
52
|
ca_cert_file=None,
|
@@ -65,7 +65,7 @@ class TestAuthManager:
|
|
65
65
|
"""Test successful AuthManager initialization."""
|
66
66
|
assert self.auth_manager.config == self.auth_config
|
67
67
|
assert self.auth_manager.permission_manager == self.mock_permission_manager
|
68
|
-
assert self.auth_manager._api_keys == {"
|
68
|
+
assert self.auth_manager._api_keys == {"test_api_key_123": "test_user"}
|
69
69
|
assert self.auth_manager._jwt_secret == "test_jwt_secret_key_32_chars_long"
|
70
70
|
assert isinstance(self.auth_manager._token_cache, dict)
|
71
71
|
assert isinstance(self.auth_manager._session_store, dict)
|
@@ -429,8 +429,8 @@ class TestAuthManager:
|
|
429
429
|
success = self.auth_manager.add_api_key("new_user", "new_api_key_456789")
|
430
430
|
|
431
431
|
assert success is True
|
432
|
-
assert "
|
433
|
-
assert self.auth_manager._api_keys["
|
432
|
+
assert "new_api_key_456789" in self.auth_manager._api_keys
|
433
|
+
assert self.auth_manager._api_keys["new_api_key_456789"] == "new_user"
|
434
434
|
|
435
435
|
def test_add_api_key_invalid_input(self):
|
436
436
|
"""Test API key addition with invalid input."""
|
@@ -456,12 +456,12 @@ class TestAuthManager:
|
|
456
456
|
"""Test successful API key removal."""
|
457
457
|
# Add a key first
|
458
458
|
self.auth_manager.add_api_key("temp_user", "temp_key_123456789")
|
459
|
-
assert "
|
459
|
+
assert "temp_key_123456789" in self.auth_manager._api_keys
|
460
460
|
|
461
461
|
# Remove the key
|
462
462
|
success = self.auth_manager.remove_api_key("temp_user")
|
463
463
|
assert success is True
|
464
|
-
assert "
|
464
|
+
assert "temp_key_123456789" not in self.auth_manager._api_keys
|
465
465
|
|
466
466
|
def test_remove_api_key_not_found(self):
|
467
467
|
"""Test API key removal for non-existent user."""
|
@@ -32,8 +32,13 @@ from mcp_security_framework.utils.cert_utils import (
|
|
32
32
|
extract_roles_from_certificate,
|
33
33
|
get_certificate_expiry,
|
34
34
|
get_certificate_serial_number,
|
35
|
+
get_crl_info,
|
36
|
+
is_certificate_revoked,
|
35
37
|
is_certificate_self_signed,
|
38
|
+
is_crl_valid,
|
36
39
|
parse_certificate,
|
40
|
+
parse_crl,
|
41
|
+
validate_certificate_against_crl,
|
37
42
|
validate_certificate_chain,
|
38
43
|
validate_certificate_format,
|
39
44
|
validate_certificate_purpose,
|
@@ -508,3 +513,166 @@ class TestCertificateFormatConversion:
|
|
508
513
|
extract_public_key("invalid_cert_data")
|
509
514
|
|
510
515
|
assert "Public key extraction failed" in str(exc_info.value)
|
516
|
+
|
517
|
+
|
518
|
+
class TestCRLFunctionality:
|
519
|
+
"""Test suite for CRL (Certificate Revocation List) functionality."""
|
520
|
+
|
521
|
+
@staticmethod
|
522
|
+
def create_test_crl():
|
523
|
+
"""Create a test CRL for testing."""
|
524
|
+
# Generate private key for CRL issuer
|
525
|
+
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
526
|
+
|
527
|
+
# Create issuer name
|
528
|
+
issuer = x509.Name([
|
529
|
+
x509.NameAttribute(NameOID.COMMON_NAME, "Test CA"),
|
530
|
+
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Test Organization"),
|
531
|
+
x509.NameAttribute(NameOID.COUNTRY_NAME, "US"),
|
532
|
+
])
|
533
|
+
|
534
|
+
# Create CRL
|
535
|
+
now = datetime.now(timezone.utc)
|
536
|
+
crl = x509.CertificateRevocationListBuilder().issuer_name(
|
537
|
+
issuer
|
538
|
+
).last_update(
|
539
|
+
now
|
540
|
+
).next_update(
|
541
|
+
now + timedelta(days=30)
|
542
|
+
).add_extension(
|
543
|
+
x509.CRLNumber(1),
|
544
|
+
critical=False,
|
545
|
+
).sign(private_key, hashes.SHA256())
|
546
|
+
|
547
|
+
return crl, private_key
|
548
|
+
|
549
|
+
def test_parse_crl_success(self):
|
550
|
+
"""Test successful CRL parsing."""
|
551
|
+
crl, _ = self.create_test_crl()
|
552
|
+
crl_pem = crl.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
553
|
+
|
554
|
+
parsed_crl = parse_crl(crl_pem)
|
555
|
+
|
556
|
+
assert parsed_crl is not None
|
557
|
+
assert isinstance(parsed_crl, x509.CertificateRevocationList)
|
558
|
+
assert "Test CA" in str(parsed_crl.issuer)
|
559
|
+
|
560
|
+
def test_parse_crl_invalid_data(self):
|
561
|
+
"""Test CRL parsing with invalid data."""
|
562
|
+
with pytest.raises(CertificateError) as exc_info:
|
563
|
+
parse_crl("invalid_crl_data")
|
564
|
+
|
565
|
+
assert "CRL parsing failed" in str(exc_info.value)
|
566
|
+
|
567
|
+
def test_is_certificate_revoked_not_revoked(self):
|
568
|
+
"""Test certificate revocation check when certificate is not revoked."""
|
569
|
+
# Create test certificate and CRL
|
570
|
+
cert, _ = TestCertificateCreation.create_test_certificate()
|
571
|
+
cert_pem = cert.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
572
|
+
crl, _ = self.create_test_crl()
|
573
|
+
crl_pem = crl.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
574
|
+
|
575
|
+
# Certificate should not be revoked since it's not in the CRL
|
576
|
+
is_revoked = is_certificate_revoked(cert_pem, crl_pem)
|
577
|
+
assert is_revoked is False
|
578
|
+
|
579
|
+
def test_is_certificate_revoked_invalid_cert(self):
|
580
|
+
"""Test certificate revocation check with invalid certificate."""
|
581
|
+
crl, _ = self.create_test_crl()
|
582
|
+
crl_pem = crl.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
583
|
+
|
584
|
+
with pytest.raises(CertificateError) as exc_info:
|
585
|
+
is_certificate_revoked("invalid_cert", crl_pem)
|
586
|
+
|
587
|
+
assert "Certificate revocation check failed" in str(exc_info.value)
|
588
|
+
|
589
|
+
def test_validate_certificate_against_crl_not_revoked(self):
|
590
|
+
"""Test certificate validation against CRL when not revoked."""
|
591
|
+
# Create test certificate and CRL
|
592
|
+
cert, _ = TestCertificateCreation.create_test_certificate()
|
593
|
+
cert_pem = cert.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
594
|
+
crl, _ = self.create_test_crl()
|
595
|
+
crl_pem = crl.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
596
|
+
|
597
|
+
result = validate_certificate_against_crl(cert_pem, crl_pem)
|
598
|
+
|
599
|
+
assert result["is_revoked"] is False
|
600
|
+
assert "serial_number" in result
|
601
|
+
assert "crl_issuer" in result
|
602
|
+
assert "crl_last_update" in result
|
603
|
+
assert "crl_next_update" in result
|
604
|
+
|
605
|
+
def test_validate_certificate_against_crl_invalid_data(self):
|
606
|
+
"""Test certificate validation against CRL with invalid data."""
|
607
|
+
with pytest.raises(CertificateError) as exc_info:
|
608
|
+
validate_certificate_against_crl("invalid_cert", "invalid_crl")
|
609
|
+
|
610
|
+
assert "Certificate CRL validation failed" in str(exc_info.value)
|
611
|
+
|
612
|
+
def test_is_crl_valid_success(self):
|
613
|
+
"""Test CRL validation success."""
|
614
|
+
crl, _ = self.create_test_crl()
|
615
|
+
crl_pem = crl.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
616
|
+
|
617
|
+
is_valid = is_crl_valid(crl_pem)
|
618
|
+
assert is_valid is True
|
619
|
+
|
620
|
+
def test_is_crl_valid_invalid_data(self):
|
621
|
+
"""Test CRL validation with invalid data."""
|
622
|
+
with pytest.raises(CertificateError) as exc_info:
|
623
|
+
is_crl_valid("invalid_crl_data")
|
624
|
+
|
625
|
+
assert "CRL validation failed" in str(exc_info.value)
|
626
|
+
|
627
|
+
def test_get_crl_info_success(self):
|
628
|
+
"""Test CRL information extraction success."""
|
629
|
+
crl, _ = self.create_test_crl()
|
630
|
+
crl_pem = crl.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
631
|
+
|
632
|
+
info = get_crl_info(crl_pem)
|
633
|
+
|
634
|
+
assert "issuer" in info
|
635
|
+
assert "last_update" in info
|
636
|
+
assert "next_update" in info
|
637
|
+
assert "revoked_certificates_count" in info
|
638
|
+
assert "status" in info
|
639
|
+
assert "version" in info
|
640
|
+
assert "signature_algorithm" in info
|
641
|
+
assert "signature" in info
|
642
|
+
assert info["revoked_certificates_count"] == 0
|
643
|
+
assert info["status"] == "valid"
|
644
|
+
|
645
|
+
def test_get_crl_info_invalid_data(self):
|
646
|
+
"""Test CRL information extraction with invalid data."""
|
647
|
+
with pytest.raises(CertificateError) as exc_info:
|
648
|
+
get_crl_info("invalid_crl_data")
|
649
|
+
|
650
|
+
assert "CRL information extraction failed" in str(exc_info.value)
|
651
|
+
|
652
|
+
def test_validate_certificate_chain_with_crl(self):
|
653
|
+
"""Test certificate chain validation with CRL."""
|
654
|
+
# Create test certificate and CA certificate
|
655
|
+
cert, _ = TestCertificateCreation.create_test_certificate()
|
656
|
+
cert_pem = cert.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
657
|
+
ca_cert, _ = TestCertificateCreation.create_test_certificate()
|
658
|
+
ca_cert_pem = ca_cert.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
659
|
+
|
660
|
+
# Create test CRL
|
661
|
+
crl, _ = self.create_test_crl()
|
662
|
+
crl_pem = crl.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
663
|
+
|
664
|
+
# Test validation with CRL (should pass since certificate is not revoked)
|
665
|
+
is_valid = validate_certificate_chain(cert_pem, ca_cert_pem, crl_pem)
|
666
|
+
assert is_valid is True
|
667
|
+
|
668
|
+
def test_validate_certificate_chain_without_crl(self):
|
669
|
+
"""Test certificate chain validation without CRL."""
|
670
|
+
# Create test certificate and CA certificate
|
671
|
+
cert, _ = TestCertificateCreation.create_test_certificate()
|
672
|
+
cert_pem = cert.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
673
|
+
ca_cert, _ = TestCertificateCreation.create_test_certificate()
|
674
|
+
ca_cert_pem = ca_cert.public_bytes(serialization.Encoding.PEM).decode('utf-8')
|
675
|
+
|
676
|
+
# Test validation without CRL
|
677
|
+
is_valid = validate_certificate_chain(cert_pem, ca_cert_pem)
|
678
|
+
assert is_valid is True
|