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

version» Context lines:

pike.git/lib/modules/Standards.pmod/X509.pmod:969:      //! Decodes a certificate, checks the signature. Returns the   //! TBSCertificate structure, or 0 if decoding or verification failes.   //! The valid time range for the certificate is not checked.   //!   //! Authorities is a mapping from (DER-encoded) names to a verifiers.   //!   //! @note   //! This function allows self-signed certificates, and it doesn't   //! check that names or extensions make sense. - TBSCertificate verify_certificate(string s, mapping(string:Verifier) authorities) + TBSCertificate verify_certificate(string s, +  mapping(string:Verifier|array(Verifier)) authorities)   {    object cert = Standards.ASN1.Decode.simple_der_decode(s);       TBSCertificate tbs = decode_certificate(cert);    if (!tbs) return 0;    -  object v; +  array(Verifier)|Verifier verifiers;       if (tbs->issuer->get_der() == tbs->subject->get_der())    {    DBG("Self signed certificate: %O\n", tbs->public_key); -  v = tbs->public_key; +  verifiers = ({ tbs->public_key });    } -  else -  v = authorities[tbs->issuer->get_der()]; +  else { +  verifiers = authorities[tbs->issuer->get_der()]; +  if (objectp(verifiers)) verifiers = ({ verifiers }); +  }    -  return v && v->verify(cert[1], -  cert[0]->get_der(), -  cert[2]->value) -  && tbs; +  foreach(verifiers || ({}), Verifier v) { +  if (v->verify(cert[1], cert[0]->get_der(), cert[2]->value)) +  return tbs;    } -  +  return 0; + }      //! Decodes a root certificate using @[decode_certificate] and   //! verifies that all extensions mandated for root certificates are   //! present and valid.   TBSCertificate verify_root_certificate(string s)   {    TBSCertificate tbs = decode_certificate(s);    if(!tbs) return 0;       multiset crit = tbs->critical + (<>);
pike.git/lib/modules/Standards.pmod/X509.pmod:1091:   //! certificate should be a DER-encoded certificate.   //! @param authorities   //! A mapping from (DER-encoded) names to verifiers.   //! @param require_trust   //! Require that the certificate be traced to an authority, even if   //! it is self signed.   //!   //! See @[Standards.PKCS.Certificate.get_dn_string] for converting the   //! RDN to an X500 style string.   mapping verify_certificate_chain(array(string) cert_chain, -  mapping(string:Verifier) authorities, +  mapping(string:Verifier|array(Verifier)) authorities,    int|void require_trust)   {    mapping m = ([ ]);   #define ERROR(X) do { \    DBG("Error " #X "\n"); \    m->verified=0; m->error_code=(X); m->error_cert=idx; \    return m; \    } while(0)       int len = sizeof(cert_chain);
pike.git/lib/modules/Standards.pmod/X509.pmod:1119:    if(!tbs)    ERROR(CERT_INVALID);       int idx = len-idx-1;    chain_cert[idx] = cert;    chain_obj[idx] = tbs;    }       foreach(chain_obj; int idx; TBSCertificate tbs)    { -  Verifier v; +  array(Verifier)|Verifier verifiers;       if(idx == 0) // The root cert    { -  v = authorities[tbs->issuer->get_der()]; +  verifiers = authorities[tbs->issuer->get_der()];       // if we don't know the issuer of the root certificate, and we    // require trust, we're done. -  if(!v && require_trust) +  if(!verifiers && require_trust)    ERROR(CERT_ROOT_UNTRUSTED);       // Is the root self signed?    if (tbs->issuer->get_der() == tbs->subject->get_der())    {    DBG("Self signed certificate\n");    m->self_signed = 1;       // always trust our own authority first, even if it is self signed. -  if(!v) -  v = tbs->public_key; +  if(!verifiers) +  verifiers = ({ tbs->public_key }); +  } else if (objectp(verifiers)) { +  verifiers = ({ verifiers });    }    }       else // otherwise, we make sure the chain is unbroken.    {    // is the certificate in effect (time-wise)?    int my_time = time();       // Check not_before. We want the current time to be later.    if(my_time < tbs->not_before)
pike.git/lib/modules/Standards.pmod/X509.pmod:1162:    if(my_time > tbs->not_after)    ERROR(CERT_TOO_OLD);       // is the issuer of this certificate the subject of the previous    // (more rootward) certificate?    if(tbs->issuer->get_der() != chain_obj[idx-1]->subject->get_der())    ERROR(CERT_CHAIN_BROKEN);       // the verifier for this certificate should be the public key of    // the previous certificate in the chain. -  v = chain_obj[idx-1]->public_key; +  verifiers = ({ chain_obj[idx-1]->public_key });    }    -  if (v) -  { +  int verified; +  foreach(verifiers || ({}), Verifier v) {    if( v->verify(chain_cert[idx][1],    chain_cert[idx][0]->get_der(),    chain_cert[idx][2]->value)    && tbs)    {    DBG("signature is verified..\n"); -  m->verified = 1; +  m->verified = verified = 1;       // if we're the root of the chain and we've verified, this is    // the authority.    if(idx == 0)    m->authority = tbs->issuer;       if(idx == sizeof(chain_cert)-1) m->cn = tbs->subject; -  +  break;    } -  else +  } +  if (!verified)    ERROR(CERT_BAD_SIGNATURE);    } -  } +     return m;      #undef ERROR   }      #endif