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

version» Context lines:

pike.git/lib/modules/Standards.pmod/X509.pmod:28:      //!   constant CERT_CHAIN_BROKEN = 4;      //!   constant CERT_ROOT_UNTRUSTED = 5;      //!   constant CERT_BAD_SIGNATURE = 6;    - //! + #if 0 + // A CA certificate does not have the CA basic constraint.   constant CERT_UNAUTHORIZED_CA = 7; -  + #endif      protected {    MetaExplicit extension_sequence = MetaExplicit(2, 3);    MetaExplicit version_integer = MetaExplicit(2, 0);       mapping algorithms = ([   #if constant(Crypto.MD2)    Identifiers.rsa_md2_id->get_der() : Crypto.MD2,   #endif    Identifiers.rsa_md5_id->get_der() : Crypto.MD5,
pike.git/lib/modules/Standards.pmod/X509.pmod:150:   //! @param ttl   //! The validity of the certificate, in seconds, starting from   //! creation date.   //!   //! @param name   //! List of properties to create distinguished name from.   //!   //! @param extensions   //! List of extensions as ASN.1 structures.   //! + //! @param h + //! The hash function to use for the certificate. Must be one of the + //! standardized PKCS hashes to be used with the given Crypto. By + //! default @[Crypto.SHA256] is selected for both RSA and DSA. + //!   //! @param serial   //! Serial number of the certificate. Defaults to generating a UUID   //! version1 value with random node. Some browsers will refuse   //! different certificates from the same signer with the same serial   //! number.   string make_selfsigned_certificate(Crypto.RSA|Crypto.DSA c, int ttl,    mapping|array name, array|void extensions,    void|Crypto.Hash h, void|int serial)   {    if(!serial)
pike.git/lib/modules/Standards.pmod/X509.pmod:516:      //! 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 authorities) + TBSCertificate verify_certificate(string s, mapping(string:Verifier) authorities)   {    object cert = Standards.ASN1.Decode.simple_der_decode(s);       TBSCertificate tbs = decode_certificate(cert);    if (!tbs) return 0;       object v;       if (tbs->issuer->get_der() == tbs->subject->get_der())    {
pike.git/lib/modules/Standards.pmod/X509.pmod:551:   //! chain is unbroken, and that all certificates are in effect   //! (time-wise.)   //!   //! Returns a mapping with the following contents, depending   //! on the verification of the certificate chain:   //!   //! @mapping   //! @member int "error_code"   //! Error describing type of verification failure, if verification failed.   //! May be one of the following: @[CERT_TOO_NEW], @[CERT_TOO_OLD], - //! @[CERT_ROOT_UNTRUSTED], @[CERT_BAD_SIGNATURE], @[CERT_INVALID], - //! @[CERT_UNAUTHORIZED_CA] or @[CERT_CHAIN_BROKEN] + //! @[CERT_ROOT_UNTRUSTED], @[CERT_BAD_SIGNATURE], @[CERT_INVALID] + //! or @[CERT_CHAIN_BROKEN]   //! @member int "error_cert"   //! Index number of the certificate that caused the verification failure.   //! @member int(0..1) "self_signed"   //! Non-zero if the certificate is self-signed.   //! @member int(0..1) "verified"   //! Non-zero if the certificate is verified.   //! @member string "authority"   //! @[Standards.ASN1.Sequence] of the authority RDN that verified   //! the chain.   //! @member string "cn"
pike.git/lib/modules/Standards.pmod/X509.pmod:579:   //! 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 authorities, int|void require_trust) +  mapping(string: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);    array chain_obj = allocate(len);    array chain_cert = allocate(len);       foreach(cert_chain; int idx; string c)    {    object cert = Standards.ASN1.Decode.simple_der_decode(c);    TBSCertificate tbs = decode_certificate(cert);    if(!tbs) -  { -  m->error_code = CERT_INVALID; -  m->error_cert = idx; -  return m; -  } +  ERROR(CERT_INVALID);       int idx = len-idx-1;    chain_cert[idx] = cert;    chain_obj[idx] = tbs;    }       foreach(chain_obj; int idx; TBSCertificate tbs)    { -  object v; +  Verifier v;      #if 0    // NOTE: disabled due to unreliable presence of cA constraint.    //    // if we are a CA certificate (we don't care about the end cert)    // make sure the CA constraint is set.    //    // should we be considering self signed certificates?    if(idx != (sizeof(chain_obj)-1))    {
pike.git/lib/modules/Standards.pmod/X509.pmod:639: Inside #if 0
   {    werror("checking for boolean: " + v->type_name + " " + v->value + "\n");    if(v->type_name == "BOOLEAN" && v->value == 1)    caok = 1;    }    }    }    }       if(! caok) -  { -  DBG("a CA certificate does not have the CA basic constraint.\n"); -  m->error_code = CERT_UNAUTHORIZED_CA; -  m->error_cert = idx; -  return m; +  ERROR(CERT_UNAUTHORIZED_CA);    } -  } +    #endif /* 0 */       if(idx == 0) // The root cert    {    v = 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) -  { -  DBG("we require trust, but haven't got it.\n"); -  m->error_code = CERT_ROOT_UNTRUSTED; -  m->error_cert = idx; -  return m; -  } +  ERROR(CERT_ROOT_UNTRUSTED);    -  // is the root self signed? +  // Is the root self signed?    if (tbs->issuer->get_der() == tbs->subject->get_der())    { -  /* A self signed certificate */ -  m->self_signed = 1; +     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;    }    }       else // otherwise, we make sure the chain is unbroken.    {    // is the certificate in effect (time-wise)?    int my_time = time();    -  // first check not_before. we want the current time to be later. +  // Check not_before. Ee want the current time to be later.    if(my_time < tbs->not_before) -  { -  m->verified = 0; -  m->error_code = CERT_TOO_NEW; -  m->error_cert = idx; -  return m; -  } +  ERROR(CERT_TOO_NEW);    -  // first check not_after. we want the current time to be earlier. +  // Check not_after. We want the current time to be earlier.    if(my_time > tbs->not_after) -  { -  m->verified = 0; -  m->error_code = CERT_TOO_OLD; -  m->error_cert = idx; -  return m; -  } +  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()) -  { -  DBG("issuer chain is broken!\n"); -  m->verified = 0; -  m->error_code = CERT_CHAIN_BROKEN; -  m->error_cert = idx; -  return m; -  } +  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;    }       if (v)    {    if( v->verify(chain_cert[idx][1],    chain_cert[idx][0]->get_der(),    chain_cert[idx][2]->value)
pike.git/lib/modules/Standards.pmod/X509.pmod:731:    m->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;    }    else -  { -  DBG("signature _not_ verified...\n"); -  m->error_code = CERT_BAD_SIGNATURE; -  m->error_cert = idx; -  m->verified = 0; -  return m; +  ERROR(CERT_BAD_SIGNATURE);    }    } -  } +     return m; -  +  + #undef ERROR   }      #endif