pike.git / lib / modules / Standards.pmod / X509.pmod

version» Context lines:

pike.git/lib/modules/Standards.pmod/X509.pmod:1525:   //! cache or always scan the directories. If a cache is used, it   //! will refresh when any certificate expires (which typically is   //! measured in years) or when asked for in unchached mode.   //!   //! @returns   //! Returns a mapping from DER-encoded issuer to @[Verifier]s   //! compatible with eg @[verify_certificate()]   //!   //! @note   //! If a certificate directory contains a file named - //! @expr{"ca-certificates.crt"@}, it is assumed to + //! @expr{"ca-certificates.crt"@}, @expr{"ca-bundle.crt"@} or + //! @expr{"ca-bundle.trust.crt"@}, it is assumed to   //! contain a concatenation of all the certificates   //! in the directory.   //!   //! @seealso   //! @[verify_certificate()], @[verify_certificate_chain()]   mapping(string:array(Verifier))    load_authorities(string|array(string)|void root_cert_dirs,    int(0..1)|void cache)   {    string key = "";
pike.git/lib/modules/Standards.pmod/X509.pmod:1625:    }    mapping(string:array(Verifier)) res = ([]);    int expire;    void update_expire(TBSCertificate tbs)    {    if(!expire) expire=tbs->not_after;    expire = min(expire, tbs->not_after);    if(tbs->not_before > time(1))    expire = min(expire, tbs->not_before);    }; +  int(0..1) add_cert(TBSCertificate|string(8bit) cert) +  { +  TBSCertificate tbs = verify_ca_certificate(cert); +  if (!tbs) return 0; +  string subj = tbs->subject->get_der(); +  if( !res[subj] || !has_value(res[subj], tbs->public_key ) ) +  { +  update_expire(tbs); +  res[subj] += ({ tbs->public_key }); +  } +  return 1; +  }; +  int(0..1) add_pem(string(8bit) pem) +  { +  int(0..1) found; +  Standards.PEM.Messages messages = Standards.PEM.Messages(pem); +  foreach(messages->get_certificates(), string m) { +  found |= add_cert(m); +  } +  return found; +  };       foreach(root_cert_dirs, string dir) {    if (!Stdio.is_dir(dir)) continue;       int found;       // Try the merged certificate files first.    foreach(({ "ca-certificates.crt", "ca-bundle.crt", "ca-bundle.trust.crt" }),    string fname) { -  string pem = Stdio.read_bytes(combine_path(dir, fname)); +  string(8bit) pem = Stdio.read_bytes(combine_path(dir, fname));    if (pem) { -  Standards.PEM.Messages messages = Standards.PEM.Messages(pem); -  foreach(messages->get_certificates(), string m) { -  TBSCertificate tbs = verify_ca_certificate(m); -  if (!tbs) continue; -  string subj = tbs->subject->get_der(); -  if( !res[subj] || !has_value(res[subj], tbs->public_key ) ) -  { -  update_expire(tbs); -  res[subj] += ({ tbs->public_key }); +  found |= add_pem(pem);    } -  found = 1; +     } -  } -  } +     if (found) continue;       // Then try the Apple KeyChain files.    foreach(({    // Mostly TLS Root CAs:    "SystemRootCertificates.keychain",       // Certificates for certifying identities and email,    // many of which are expired.    "SystemCACertificates.keychain",
pike.git/lib/modules/Standards.pmod/X509.pmod:1671:    // Old name for SystemRootCertificates.keychain.    "X509Anchors",       // Old name for SystemCACertificates.keychain.    "X509Certificates",    }), string fname) {    string keychain = Stdio.read_bytes(combine_path(dir, fname));    if (keychain) {    Apple.Keychain chain = Apple.Keychain(keychain);    foreach(chain->certs, TBSCertificate tbs) { -  if (!verify_ca_certificate(tbs)) continue; -  string subj = tbs->subject->get_der(); -  if( !res[subj] || !has_value(res[subj], tbs->public_key ) ) -  { -  update_expire(tbs); -  res[subj] += ({ tbs->public_key }); +  found |= add_cert(tbs);    } -  found = 1; +     }    } -  } +     if (found) continue;       // Fall back to trying every file.    foreach(get_dir(dir) || ({}), string fname) {    if (has_suffix(fname, ".0")) {    // Skip OpenSSL hash files for now (as they are duplicates).    continue;    }    fname = combine_path(dir, fname);    if (!Stdio.is_file(fname)) continue; -  string pem = Stdio.read_bytes(fname); +  string(8bit) pem = Stdio.read_bytes(fname);    if (!pem) continue; -  string cert = Standards.PEM.simple_decode(pem); -  if (!cert) continue; -  TBSCertificate tbs = verify_ca_certificate(cert); -  if (!tbs) continue; -  string subj = tbs->subject->get_der(); -  if( !res[subj] || !has_value(res[subj], tbs->public_key ) ) -  { -  update_expire(tbs); -  res[subj] += ({ tbs->public_key }); +  add_pem(pem);    }    } -  } +        if( authorities_cache_expire[key] || cache )    {    authorities_cache[key] = res;    authorities_cache_expire[key] = expire;    }    return res;   }      //! Decodes a certificate chain, ordered from leaf to root, and