-
Notifications
You must be signed in to change notification settings - Fork 0
security(tls): require exact trust scalar values #214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
seonghobae
wants to merge
8
commits into
main
Choose a base branch
from
security/tls-config-scalar-integrity-main-7faf
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
d523c64
test(tls): reject polymorphic trust scalar values
seonghobae 1442fdb
fix(tls): seal retained trust scalar values
seonghobae d2be915
docs(tls): define exact trust scalar boundary
seonghobae 00f7559
test(tls): reject polymorphic private-key passwords
seonghobae d3be1c0
fix(tls): seal direct private-key password values
seonghobae 6ecc1b2
docs(tls): define exact private-key secret values
seonghobae a63f054
docs(tls): record scalar integrity hardening
seonghobae 0bfc22b
docs(tls): preserve existing changelog history
seonghobae File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| """Regression coverage for exact TLS trust and identity scalar values.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from pathlib import Path | ||
|
|
||
| import pytest | ||
|
|
||
| from egressweave.tls import TLSConfiguration | ||
|
|
||
|
|
||
| class _HostileText(str): | ||
| """Expose any subclass-controlled text normalization at the TLS boundary.""" | ||
|
|
||
| def strip(self, *args: object, **kwargs: object) -> str: | ||
| """Fail if trusted configuration invokes this polymorphic method.""" | ||
| del args, kwargs | ||
| raise AssertionError("TLS configuration invoked hostile text normalization") | ||
|
|
||
|
|
||
| class _HostileBytes(bytes): | ||
| """Expose any subclass-controlled truth-value check on CA bytes.""" | ||
|
|
||
| def __len__(self) -> int: | ||
| """Fail if trusted configuration inspects polymorphic byte length.""" | ||
| raise AssertionError("TLS configuration invoked hostile byte length") | ||
|
|
||
|
|
||
| class _HostilePasswordText(str): | ||
| """Represent executable behavior hidden inside password text.""" | ||
|
|
||
|
|
||
| class _HostilePasswordBytes(bytes): | ||
| """Represent executable behavior hidden inside password bytes.""" | ||
|
|
||
|
|
||
| class _HostilePasswordBuffer(bytearray): | ||
| """Expose conversion of a mutable password subclass before retention.""" | ||
|
|
||
| def __bytes__(self) -> bytes: | ||
| """Fail if trusted construction converts a polymorphic buffer.""" | ||
| raise AssertionError("TLS configuration invoked hostile password conversion") | ||
|
|
||
|
|
||
| class _HostileTextPath: | ||
| """Return a non-exact text path from the standard path protocol.""" | ||
|
|
||
| def __fspath__(self) -> str: | ||
| """Return a text subclass that must be rejected before use.""" | ||
| return _HostileText("trust/private-ca.pem") | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "field_name", | ||
| [ | ||
| "ca_file", | ||
| "ca_path", | ||
| "client_certificate_file", | ||
| "client_private_key_file", | ||
| ], | ||
| ) | ||
| def test_tls_paths_reject_direct_text_subclasses_before_normalization( | ||
| field_name: str, | ||
| ) -> None: | ||
| """Require exact path text before any subclass-defined text method runs.""" | ||
| with pytest.raises(TypeError, match="text path"): | ||
| TLSConfiguration(**{field_name: _HostileText("identity.pem")}) # type: ignore[arg-type] | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "field_name", | ||
| [ | ||
| "ca_file", | ||
| "ca_path", | ||
| "client_certificate_file", | ||
| "client_private_key_file", | ||
| ], | ||
| ) | ||
| def test_tls_paths_reject_pathlike_text_subclasses_before_normalization( | ||
| field_name: str, | ||
| ) -> None: | ||
| """Detach one path-protocol value but reject a polymorphic text result.""" | ||
| with pytest.raises(TypeError, match="text path"): | ||
| TLSConfiguration(**{field_name: _HostileTextPath()}) # type: ignore[arg-type] | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "ca_data", | ||
| [ | ||
| _HostileText("-----BEGIN CERTIFICATE-----"), | ||
| _HostileBytes(b"deferred-der-certificate"), | ||
| ], | ||
| ) | ||
| def test_ca_data_rejects_builtin_subclasses_before_inspection(ca_data: object) -> None: | ||
| """Keep polymorphic text or bytes outside immutable trust state.""" | ||
| with pytest.raises(TypeError, match="ca_data"): | ||
| TLSConfiguration(ca_data=ca_data) # type: ignore[arg-type] | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "password", | ||
| [ | ||
| _HostilePasswordText("secret"), | ||
| _HostilePasswordBytes(b"secret"), | ||
| _HostilePasswordBuffer(b"secret"), | ||
| ], | ||
| ) | ||
| def test_private_key_password_rejects_builtin_subclasses_before_retention( | ||
| password: object, | ||
| ) -> None: | ||
| """Keep polymorphic secret scalars outside immutable TLS identity state.""" | ||
| with pytest.raises(TypeError, match="client_private_key_password"): | ||
| TLSConfiguration( | ||
| client_certificate_file="identity/client.pem", | ||
| client_private_key_password=password, # type: ignore[arg-type] | ||
| ) | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("password", ["secret", b"secret", bytearray(b"secret")]) | ||
| def test_exact_private_key_password_scalars_remain_supported(password: object) -> None: | ||
| """Preserve Python TLS loader password shapes while freezing bytearrays.""" | ||
| configuration = TLSConfiguration( | ||
| client_certificate_file="identity/client.pem", | ||
| client_private_key_password=password, # type: ignore[arg-type] | ||
| ) | ||
|
|
||
| expected = bytes(password) if type(password) is bytearray else password | ||
| assert configuration.client_private_key_password == expected | ||
| assert type(configuration.client_private_key_password) is type(expected) | ||
|
|
||
|
|
||
| def test_exact_tls_scalar_values_and_standard_paths_remain_supported() -> None: | ||
| """Preserve reviewed exact values and ordinary pathlib integration.""" | ||
| password_callback = lambda: "secret" | ||
| configuration = TLSConfiguration( | ||
| ca_file=Path("trust/roots.pem"), | ||
| ca_path="trust/roots", | ||
| ca_data=b"deferred-der-certificate", | ||
| client_certificate_file=Path("identity/client.pem"), | ||
| client_private_key_file="identity/client.key", | ||
| client_private_key_password=password_callback, | ||
| ) | ||
|
|
||
| assert configuration.ca_file == "trust/roots.pem" | ||
| assert configuration.ca_path == "trust/roots" | ||
| assert configuration.ca_data == b"deferred-der-certificate" | ||
| assert configuration.client_certificate_file == "identity/client.pem" | ||
| assert configuration.client_private_key_file == "identity/client.key" | ||
| assert configuration.client_private_key_password is password_callback |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.