Skip to content
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

tls library #394

Merged
merged 46 commits into from
Jul 4, 2023
Merged

tls library #394

merged 46 commits into from
Jul 4, 2023

Conversation

nworbnhoj
Copy link
Contributor

@nworbnhoj nworbnhoj commented Jul 3, 2023

A tls library focused on explicitly trusting Certificate Authority Certificates (requires --feature tls).

Typically, operating systems and browsers embed a list of implicitly trusted Root CA certificates.

The tls handshake involves the host offering the client a Certificate signed for authenticity by a CA, with a chain of signatures back to a Root CA. If the client trusts at least one Certificate in this chain of trust, then the handshake may progress to an encrypted connection.

It does not seem in keeping with the Precursor/Xous idea to ask users to trust any such list of Root CA Certificates.

This tls library enables the user to obtain and save trusted CA certificates to the PDDB as a personalised set of trusted Root CA certificates on which to establish a tls connection. This can be as simple for the user as responding to a modal, when making a first connection to an as yet un-trusted host. Just a couple of clicks. The developer need only call Tls::check_trust().

Note that hosts with self-signed Certificates may be probed and trusted (e.g. chat.signal.org)

A small set of shellchat commands are included to enact the base functionality:

  • net tls probe <host> will initiate a modified tls handshake with <host>, obtain the certificate chain offered by <host>, and immediately terminate the connection. A call to Tls::check_trust() will present the CA certificate chain in a modal to be individually selected and saved to PDDB if trusted.
  • net tls test <host> will attempt a normal tls handshake with <host> based on the trusted Root CA certificates in the PDDB. If the connection is successful, then a simple get is emitted, the response accepted, and the connection closed.
  • net tls mozilla trusts and saves all Root CA's in the webpki-roots crate - which contains Mozilla's root certificates. (requires --feature rootCA)
  • net list lists all trusted certificates in the PDDB
  • net deleteall deletes all trusted certificates in the PDDB

These functions are gated by 2 feature flags:

In keeping with rustls & webpki, only the critical components of each x509-Certificate are stored in the PDDB under the tls.trusted dictionary - as a rkyv archive of a tls::RustTlsOwnedTrustAuthority object.

The rustls dangerous_configuration feature is required to modify the tls handshake during a net tls probe <host>. This is because, by default, rustls drops the connection (and certificate chain) if there is no match to a trusted Root CA Certificate in the RootStore. During a probe we need to briefly trust all CA certificates in order to get hold of the CA certificate chain, and inspect it.

The shellchat net tls commands are are called from services/shellchat/src/cmds/net_cmd.rs, but located in libs/tls/src/cmd.rs in order to contain the size of services/shellchat/src/cmds/net_cmd.rs and to keep the tls cmds close to the implementation.

Native pddb calls are used throuought (std::fs free)

Considerations:

  • Some adjustments to the checkbox modal were made to allow display of milti-line options.
  • Another adjustment to increase the minimum checkbox option length.
  • there is an outstanding issue where the checkbox modal does not display options with multiple lines correctly. This impacts the display of fingerprints for some certificates with longer subjects.
  • An issue was identified with std::fs on Precursor hardware: ~~Guru Mediation~~ on an unwrap() in library/std/src/sys/xous/fs.rs:573:46 when attempting to list a dictionary with ~140 keys. It is suspected that there might be an overflow situation due to an assumption in the code that the listing will fit in 1 page.
  • It may be worth considering rendering public pddb::KEY_NAME_LEN to allow developer to avoid sending overly long key's which will be rejected by the pddb.
  • probably need a shellchat net tls delete <cert>
  • some broken code is included for a future fix if required RustlsOwnedTrustAnchor::publik_key()
  • some hosts (eg bunnyfoo.com) emit an unexpected eof error during tls handshake 🤷

presents a modal to the user to select trusted tls certificates and saves the selected certificates to the pddb
StifledCertificateVerification::verify_server_cert() will verify the certificate with the default rustls WebPkiVerifier, BUT specifically override a `CertificateError::UnknownIssuer` and return ServerCertVerified::assertion()

This allows us to use rustls to open a tls connection to a host with an untrusted certificate chain. And subsequently get to see the certificate chain, and possibly choose to trust the chain, or links in it.
save/trust all Root CA's in webpki-roots en-masse
list trusted Certificate Authority certificates
@nworbnhoj nworbnhoj marked this pull request as ready for review July 3, 2023 23:53
@bunnie
Copy link
Member

bunnie commented Jul 4, 2023

that's some really good stuff in there! I really do like how you ended up breaking the shellchat extensions into the library, that might be a pattern I start using elsewhere as well. I'll go ahead and merge this just to get it into CI and see what breaks.

@bunnie bunnie merged commit c8accf8 into betrusted-io:main Jul 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants