PEP 748: tlslib - configuration#4958
Conversation
Ease reading the diff of the next commits.
Client-side `trust_store=None` means `TrustStore.system()` but server-side it means "skip client authentication". One could think it means "skip server authentication" when used client-side, so let's not support `None` at all client-side and instead default to `TrustStore.system()`.
Documentation build overview
709 files changed ·
|
|
cc PEP authors @jvdprng and @woodruffw. |
jvdprng
left a comment
There was a problem hiding this comment.
Thanks for the PR! I left two suggestions.
jvdprng
left a comment
There was a problem hiding this comment.
On second thought, there is one additional thing we should change.
| lowest_supported_version: TLSVersion | None = None, | ||
| highest_supported_version: TLSVersion | None = None, | ||
| trust_store: TrustStore | None = None, | ||
| trust_store: TrustStore = TrustStore.system(), |
There was a problem hiding this comment.
I remember now why we had None here before: we wanted to avoid creating a shared default object in the API which should be immutable/comparable. So I think we need something else here:
- A sentinel object (we deliberately chose not to do this IIRC)
- Do not define the default, and specify that a missing
TrustStoreshould default to the system trust store. This is my preference.
There was a problem hiding this comment.
Do not define the default, and specify that a missing TrustStore should default to the system trust store. This is my preference.
I don't understand, can you add an example?
There was a problem hiding this comment.
We wanted to avoid creating a shared default object in the API which should be immutable/comparable.
I think there is room for a TrustStore.is_system(truststore) method.
There was a problem hiding this comment.
Yeah, what I was thinking of does not work. I think a larger problem is that TrustStore objects are currently not immutable. I would propose to make them immutable by freezing them (which means I need to fix some path handling in the stdlib, but that's probably fine) which would make it fine to assign the system trust store as a default parameter.
We could then consider making the configs frozen as well. What do you think?
There was a problem hiding this comment.
Making the class immutable means that implementations that require one of _path or _buffer can't have the following:
# example for an implementation that doesn't support paths
def load(trust_store):
if trust_store._buffer:
return
if trust_store._path:
with open(trust_store._path, ...) as file:
trust_store._buffer = file.read()
return
raise ValueError("TrustStore.system() is not supported")which is a pattern that is implemented in both tlslib.stdlib (buffer->path) and siotls (path->buffer).
I think we need to discuss the three TrustStore, Certificate and PrivateKey APIs more12. For the time being, I suggest we add a TrustStore.is_system() method to solve the problem at hand and have the discussion about immutability and path->buffer/buffer->path elsewhere.
def is_system(self):
return self._buffer is None and self._path is None and self._id is None+1 to have the configuration immutable. It already is a frozen dataclass in siotls. I'll push a commit to specify it in the spec.
Footnotes
-
https://discuss.python.org/t/pre-pep-discussion-revival-of-pep-543-a-unified-tls-api-for-python/51263/71: § Certificate Chain, Certificate Revocation List ↩
-
https://discuss.python.org/t/pre-pep-discussion-revival-of-pep-543-a-unified-tls-api-for-python/51263/71: § Save DER in-place ↩
There was a problem hiding this comment.
No need to change the spec, it already says that the configuration objects are immutable (emphasis mine):
For this reason, we split the responsibility of SSLContext into two separate objects, which are each split into server and client versions. The TLSServerConfiguration and TLSClientConfiguration objects act as containers for a TLS configuration: the ClientContext and ServerContext objects are instantiated with a TLSClientConfiguration and TLSServerConfiguration object, respectively, and are used to create buffers or sockets. All four objects would be immutable.
adfecae to
e14904b
Compare
TLS 1.3 and secure TLS 1.2 both require a certificate and private key server-side. Making the parameter mandatory makes it explicit that one is required. It still is optional client-side.
e14904b to
89e8de4
Compare
First time contributor 🎉
A few suggestions to make the configuration a bit more explicit. I decided to leave most of the attributes undocumented as they are pretty explicit to me, and to instead only document the few attributes that are different from the client and the server.
PEP 748: ConfigurationError is only for unsupported features
Discussed at trailofbits/tlslib.py#72 (comment)
PEP 748: certificate_chain is mandatory server-side
Discussed at https://discuss.python.org/t/pre-pep-discussion-revival-of-pep-543-a-unified-tls-api-for-python/51263/75
PEP 748: disambiguate config trust_store=None
Discussed at https://discuss.python.org/t/pre-pep-discussion-revival-of-pep-543-a-unified-tls-api-for-python/51263/78