Add a sense of purpose to SSL/TLS certificates.
Review Request #14896 — Created March 11, 2026 and updated — Latest diff uploaded
My original design for SSL/TLS certificate management combined two
important purposes into one concept of a certificate. Depending on the
call site and the presence of a private key, aCertificatecould be
used for verifying a server or authenticating the client with a server.
These are very different purposes, and needed to be managed separately.The original design led to incorrect calls in
build_ssl_context()and
thereforebuild_urlopen_kwargs(), meaning we didn't always have the
right context in place to handle the operation.This change addresses this by:
Introducing a
CertPurposeenum containingTRUST(for
cert trust/verification needs) andCLIENT(for client
authentication).A
purposefield inCertificateand all cert-related operations in
CertificateManager, and storage equivalents in the backends.A "trust" cert may not have a private key, and a "client" cert must
(although technically that cert could embed the key, we're requiring two
separate files in our implementation for now).This does change the signatures and expectations in the storage
backends, and we're not going through a deprecation cycle for that. The
reason being that, while we introduced all this in Review Board 6, we
never made actual use of it. Going through a deprecation cycle would
introduce a fair amount of complexity, and isn't worth it for something
that users haven't touched or would have had a need to build upon.One of the backwards-incompatible changes is the location of files in
the file storage backend. Both kinds of certs used to live incerts/,
but now they live incerts/client/andcerts/purpose/instead.The change is pretty straight-forward. The biggest change in behavior is
build_ssl_context(), which now passes the right kinds of certs to the
right functions.The bulk of the change is actually unit tests and testdata file
movement. We now have trust and client purpose variations for each
relevant test.As a note, there's some initial attempts at modernizing some of the
typing in this change, but it's purposefully incomplete. The rest will
be tackled separately.
All unit tests pass.