ref: a7d243ef71a1b27166c158ba148da2363402f328
dir: /pki.ms/
.am DS .ft I .. .ta 1i 2.3i 4.5i (optional to set tabs) .TL Rethinking PKI on Plan 9 .AU Ori Bernstein ori@eigenstate.org .AB Today, Plan 9 implements PKI using thumbprint files. This does not work well in today's world of rapidly expiring certificates and short lived private keys. As a result, we propose a factotum-scented file server, .IR auth/pki , which will handle the X509 certificate chain validation that today's internet infrastructure inspects. .AE .NH 1 How does Plan 9 Handle X509 Certificate Validation? .PP Today, Plan 9 punts on the problem of verifying certificates. While we implement X509 certificate parsing, and programs can verify thumbprints for themselves, we do not implement the verification algorithms. .PP In the past, this approach was more viable than it is today. TLS itself was used far less frequently. Furthermore, when it was used, the certificates were issued for a longer period, and the private keys used in the certificate were also rotated relatively rarely. However, automated tooling around letsencrypt, tools used in practice at larger web services, and the general web ecosystem has moved towards reissuing not just the certificates associated with a private key, but the private key itself. .PP As a result, it's become less and less viable to verify certificates by manually pinning the hash of their public key: The public key of many certificates in use is unnecessarily rotated on a regular basis, forcing system administrators to update their lists of allowed certs. .PP As a result, we need to either stop verifying certificates for systems that we do not administer entirely, or we need to verify them the .I "proper" way. .PP To date, we have selected the second option. This WIP explores what changing the situation may look like. .NH 1 What's a PKI? .PP Before diving into what certificates are, and how they're verified, let's review how the X509 PKI infrastructure is designed to work. .PP X509 PKI is a system used to manage the distribution and verification of public keys. The goal of PKI is to establish a method to bind an identity to a public key, via a centrally managed web of trust. The verification and identity binding is designed to be delegatable, such that not all trust is centralized in one authority. Instead, a cartel of certificate authorities is able to control the issuing of trusted X509 certificates. .PP When discussing PKI, we need to start with several definitions. .PP .B "Certificate authorities" issue and sign certificates. An example of a certificate authority may be Verisign or Lets Encrypt. .B "registration authorities" are responsibile for verifying the identity of entities who wish a certificate to be issued. Often, but not always, they are the same entity as the certificate authority.h The issued certificates are registered in a "Central Directory". .PP On the client side, the clients keep their .B "roots of trust" in a .B "certifcate store" . When validating a certificate, a .B certificate chain is constructed. A certificate chain consists of a sequence of certificates, each signed by the next certificate in the chain. For a valid certificate, all certificates in the chain must be valid, must not be revoked, and the final certificate must be a root of trust. .NH 1 An Introduction to X509 Certificate Validation .PP Once a certificate has been issued, servers will present them via TLS to clients, and clients may optionally present them to servers. These certificates are presented in order to verify the identity of the server to the client, and if so desired, of the client to the server. .PP Conceptually, this verification is simple: First, the verifier ensures that the provided certificate is, in fact, issued for the resource being verified. If a user is attempting to access .IR https://bank.com , but an an attacker intercepts the TLS handshake, and presents a certificate for .IR https://stealyourmoney.com , then it would do no good for the browser to verify that the certificates have been signed. .PP Next, if the certificate chain is built. Until the .I root of trust is reached, the certificates are is a known trusted certificate, or a .IR "root of trust" , then the validation is complete. If it is not, then the next element of the chain -- ie, the signer of the certificate, is located, and appended to the verification chain. This continues until the chain reaches a root of trust. Once the full chain is discovered, the signature of each element in the chain is verifed against the signature of the next element. If all signatures pass, the names are considered valid. .NH 1 Introducing Auth/pki .PP When Plan 9 security was initially redesigned, factotum was introduced to remove cryptographhic code from individual programs. The goal was to isolate it in an auditable system that would keep secrets away from buggy code. .PP When revisiting the way that X509 certificates were handled in Plan 9, similar considerations seemed relevant. Initially, the idea was to put certificate validation into factotum directly, as checking whether a certificate is valid looks similar to checking whether a user should be permitted. However, as it became clear how X509 got validated, it became clear that X509 should not be allowed near any security critical components of the system, and the validation was separated into its own system. .PP Similar to factotum, auth/pki mounts itself as a file system. The file system contains a .I ctl file, which is opened in order to write the .I PEM chain into. Each certificate in the chain is written, from the leaf to the root, and auth/pem verifies it using the expected verification rules. The protocol looks something like: .P1 -> verify host 'hostname' -> cert der nbytes -> <bytes of cert data> -> cert der nbytes -> <bytes of cert data> ... -> done <- accept .P2 .NH 1 Changes to the System .PP While auth/pki has a simple interface, the way we handle TLS throughout the system is not structured in a way that can take advantage of it. In order to take advantage of auth/pki, a number of changes are needed. .PP The .I tlsClient call currently has a very poor interface, making changes unnecessarily difficult. Specifically, it uses a struct where the TLS interface allocates members, but where the caller of the API is expected to free them. This means that if anything changes about the contents of the tlsConn struct, all callers must be updated to free new fields. While callers could be updated to match additional certificate chain and hostname fields, we chose to go through and fix the API properly, allowing future revisions of TLS handling to be implemented with less pain. .PP Additionally, in order for TLS to validate a connection, we need to not only show that the TLS connection presents a certificate chain, we also need to ensure that the certificate chain is issuesd for the resource that we are accessing. This means that we need to know the name of the resource, as presented by the certificate chain. .PP This is made difficult to do in the general case, due to the way that dial strings work, amd the indirection that ndb and the connection server provide. In order to solve this, at the minimum we need to provide a way to parse dial strings and extract the host name from them. This seems sufficient for now, but in the longer term we may need help from the connection server to provide the canonical name for a resource. .NH 1 Current Status .PP Currently, code exists to implement some level of PKI validation. Several of the changes to the system mentioned above have been implemented, and some programs have been patched in a private branch in order to make them work with .I auth/pki . .PP However, the name validation is currently done very crudely. The pki validation assumes that names are unstructured blobs of data, and that they only match if they are an exact byte for byte match. This is the way that things should work in a reasonable world, but it's not what happens in our world. .PP As a result, before this can be shipped, the full name validation algorithms from .I "RFC 6125" and .I "RFC 9618" . Additionally, it would make sense to add support for offline certificate revocation lists. .NH 1 References .LP [1] P. Saint-Andre, J. Jodges, .I "``RFC 6125''", 2011 .LP [2] D. Benjamin, .I "``RFC 9618''", 2024 .LP [2] D. Benjamin, .I "``RFC 9618''", 2024 .LP [3] Recommendation X.509, .I "``Information Technology--Open Systems Interconnection--The Directory: Authentication``" ITU