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

version» Context lines:

pike.git/lib/modules/Standards.pmod/X509.pmod:404:       //! Certificate issuer.    void `issuer=(Sequence i)    {    low_set(2, i);    }    Sequence `issuer()    {    return low_get_sequence(2);    } +  // Attempt to create a presentable string from the issuer DER. +  string issuer_str() +  { +  return dn_str(issuer); +  }       //!    void `validity=(Sequence v)    {    // FIXME: Validate?    low_set(3, v);    }    Sequence `validity()    {    return low_get_sequence(3);
pike.git/lib/modules/Standards.pmod/X509.pmod:468:    low_set(4, s);    }    Sequence `subject()    {    return low_get_sequence(4);    }       // Attempt to create a presentable string from the subject DER.    string subject_str()    { -  Sequence subj = low_get_sequence(4); +  return dn_str(subject); +  } +  +  string dn_str(Sequence dn) +  {    mapping ids = ([]); -  foreach(subj->elements, Compound pair) +  foreach(dn->elements, Compound pair)    {    if(pair->type_name!="SET" || !sizeof(pair)) continue;    pair = pair[0];    if(pair->type_name!="SEQUENCE" || sizeof(pair)!=2)    continue;    if(pair[0]->type_name=="OBJECT IDENTIFIER" &&    pair[1]->value && !ids[pair[0]])    ids[pair[0]] = pair[1]->value;    }   
pike.git/lib/modules/Standards.pmod/X509.pmod:1683:   #define ERROR(X) do { \    DBG("Error " #X "\n"); \    m->verified=0; m->error_code|=(X); m->error_cert=idx; \    } while(0)   #define FATAL(X) do { ERROR(X); return m; } while(0)       // Decode all certificates in the chain. Leaf is first and root is    // last.       int len = sizeof(cert_chain); -  array chain_obj = allocate(len); -  array chain_cert = allocate(len); +  array chain_obj = ({}); +  array chain_cert = ({}); +  // Ignore certificates that aren't issuers of the leaf certificate. +  bool ignore_extraneous = true;    -  +  string last_issuer;    foreach(cert_chain; int idx; string c)    {    object cert = Standards.ASN1.Decode.secure_der_decode(c);    TBSCertificate tbs = decode_certificate(cert);    if(!tbs)    FATAL(CERT_INVALID);    -  int idx = len-idx-1; -  chain_cert[idx] = cert; -  chain_obj[idx] = tbs; +  string subject = tbs->subject->get_der(); +  if (ignore_extraneous && last_issuer && subject != last_issuer) +  { +  // This doesn't look relevant for validating the previous (closer to +  // the leaf) certificate. +  DBG("Skipping %q\n", tbs->subject_str()); +  continue;    } -  +  DBG("Adding %q to chain\n", tbs->subject_str()); +  +  // This is the leaf or is needed to validate the previous certificate. +  last_issuer = tbs->issuer->get_der(); +  chain_cert = ({ cert }) + chain_cert; +  chain_obj = ({ tbs }) + chain_obj; +  +  if (ignore_extraneous && has_index(authorities, last_issuer)) +  { +  // We've reached a certificate signed by a root we trust, end here. +  DBG("Ending at %q - signed by root %q\n", tbs->subject_str(), tbs->issuer_str()); +  break; +  } +  } +  +  // Update length since we've filtered the certificate chain a bit. +  len = sizeof(chain_obj);    m->certificates = chain_obj;       // Chain is now reversed so root is first and leaf is last.       int my_time = time();    foreach(chain_obj; int idx; TBSCertificate tbs)    {    array(Verifier)|Verifier verifiers;       // Check not_before. We want the current time to be later.
pike.git/lib/modules/Standards.pmod/X509.pmod:1784:    }       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 = verified = 1; +  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;    }    }    if (!verified)    ERROR(CERT_BAD_SIGNATURE); -  +  else if (zero_type(m->error_code)) // only if no error occured... +  m->verified = verified;    }    return m;      #undef ERROR   #undef FATAL   }      //! DWIM-parse the ASN.1-sequence for a private key.   Crypto.Sign.State parse_private_key(Sequence seq)   {