iyi

Standard library, 0.18.0

std/system_roots

The root certificates the operating system trusts, read as std/x509 certificates: the roots a TLS client hands X509.verify.

import std/system_roots to use it. Source: src/std/system_roots.iyi at v0.18.0.

  import std/system_roots::{SystemRoots}
  import std/x509::{X509}
  store = SystemRoots.load.or_panic        # certificates, unreadable, source
  X509.verify(leaf, intermediates, store.certificates, "example.com")

Each platform's own store, as Go's crypto/x509 reads it:

  • Everywhere: $SSL_CERT_FILE and every file in each directory of $SSL_CERT_DIR when either is set - the variables OpenSSL reads, which is how a container or a test names its own roots. The directories are a list as PATH is: : between them, ; on Windows, where a drive letter owns the colon.
  • Linux, otherwise: the first bundle of the ones the distributions write (Debian's, Fedora's, openSUSE's, RHEL's, Alpine's), and when there is none, every file in /etc/ssl/certs and /etc/pki/tls/certs.
  • darwin: Security.framework's system anchors (SecTrustCopyAnchorCertificates), with the trust settings an administrator and then the user made on top (SecTrustSettings, the user's over the administrator's): a certificate trusted as a root with no constraint is added, and one denied, for any use, is taken away. A setting constrained to a policy, an application or a key usage is not one this can apply, so it adds nothing; a denial is honoured whatever it is constrained to, as refusing too much is the safe side.
  • Windows: crypt32's ROOT store (CertOpenSystemStoreW), less what the Disallowed store holds. Windows fills the ROOT store as it meets roots it does not have yet, through its own chain building; a root it has never fetched is not there to read, and a chain to it is refused.

The same certificate twice is kept once. One that std/x509 cannot read - a key type it does not take, a DSA root on an old system - is counted in unreadable, not an error: a store is used for what it holds. No certificate at all is an X509Error naming where it looked.

This module is what reaches the operating system (iyi mod reach): std/x509 itself is pure computation, and a program that brings its own roots does not link crypt32 or Security.framework.

SystemRootsstruct

std/system_rootsiyi doc src/std/system_roots.iyi
pub struct SystemRoots
  # The certificates, each once, in the order the store gave them.
  def certificates : Array(Certificate)
  def initialize(certificates : Array(Certificate), unreadable : Int32, source : String)
  # The operating system's trusted roots, or why there are none.
  def self.load : SystemRoots | X509Error
  # Where they came from: files, or the platform's store by name.
  def source : String
  # How many entries std/x509 could not read.
  def unreadable : Int32
end