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

version» Context lines:

pike.git/lib/modules/Standards.pmod/X509.pmod:1142:   //! @[decode_certificate()], @[make_tbs()]   Sequence sign_tbs(TBSCertificate tbs,    Crypto.Sign sign, Crypto.Hash hash)   {    return Sequence(({ [object(Sequence)]tbs,    sign->pkcs_signature_algorithm_id(hash),    BitString(sign->pkcs_sign(tbs->get_der(), hash)),    }));   }    - //! Low-level function for creating a self-signed certificate. + //! Low-level function for creating a signed certificate.   //!   //! @param issuer   //! Distinguished name for the issuer.   //! See @[Standards.PKCS.Certificate.build_distinguished_name].   //!   //! @param c - //! RSA, DSA or ECDSA parameters for the issuer. - //! Both the public and the private keys need to be set. - //! See @[Crypto.RSA], @[Crypto.DSA] and @[Crypto.ECC.Curve.ECDSA]. + //! RSA, DSA or ECDSA parameters for the subject. Only the public + //! key needs to be set. See @[Crypto.RSA], @[Crypto.DSA] and + //! @[Crypto.ECC.Curve.ECDSA].   //! -  + //! @param ca + //! RSA, DSA or ECDSA parameters for the issuer. Only the private + //! key needs to be set. See @[Crypto.RSA], @[Crypto.DSA] and + //! @[Crypto.ECC.Curve.ECDSA]. + //!   //! @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.   //!   //! @param subject   //! Distinguished name for the issuer.   //! See @[Standards.PKCS.Certificate.build_distinguished_name].   //!   //! @param public_key   //! DER-encoded RSAPublicKey structure.
pike.git/lib/modules/Standards.pmod/X509.pmod:1179:   //! Validity time in seconds for this signature to be valid.   //!   //! @param extensions   //! Set of extensions.   //!   //! @returns   //! Returns a DER-encoded certificate.   //!   //! @seealso   //! @[make_selfsigned_certificate()], @[make_tbs()], @[sign_tbs()] - string sign_key(Sequence issuer, Crypto.Sign c, Crypto.Hash h, + string sign_key(Sequence issuer, Crypto.Sign c, Crypto.Sign ca, Crypto.Hash h,    Sequence subject, int serial, int ttl, array|mapping|void extensions)   {    Sequence algorithm_id = c->pkcs_signature_algorithm_id(h);    if(!algorithm_id) error("Can't use %O for %O.\n", h, c);    if(serial<0) error("Serial number needs to be >=0.\n");       if( mappingp(extensions) )    {    mapping(Identifier:Sequence) m = [mapping]extensions;    array(Sequence) a = ({});    foreach( sort(indices(m)), Identifier i )    a += ({ m[i] });    extensions = a;    }       return sign_tbs(make_tbs(issuer, algorithm_id,    subject, c->pkcs_public_key(),    Integer(serial), ttl, extensions), -  c, h)->get_der(); +  ca, h)->get_der();   }      //! Creates a certificate extension with the @[id] as identifier and   //! @[ext] as the extension payload. If the @[critical] flag is set   //! the extension will be marked as critical.   Sequence make_extension(Identifier id, Object ext, void|int critical)   {    array seq = ({ id });    if( critical )    seq += ({ Boolean(1) });
pike.git/lib/modules/Standards.pmod/X509.pmod:1274:       if(!extensions) extensions = ([]);       // While RFC 3280 section 4.2.1.2 suggest to only hash the BIT    // STRING part of the subjectPublicKey, it is only a suggestion.    add("subjectKeyIdentifier",    OctetString( Crypto.SHA1.hash(c->pkcs_public_key()->get_der()) ));    add("keyUsage", build_keyUsage(KU_digitalSignature|KU_keyEncipherment), 1);    add("basicConstraints", Sequence(({Boolean(0)})), 1);    -  return sign_key(dn, c, h||Crypto.SHA256, dn, serial, ttl, extensions); +  return sign_key(dn, c, c, h||Crypto.SHA256, dn, serial, ttl, extensions);   }    -  + string make_site_certificate(TBSCertificate ca, Crypto.Sign ca_key, +  Crypto.Sign c, int ttl, mapping|array name, +  mapping|void extensions, +  void|Crypto.Hash h, void|int serial) + { +  if(!serial) +  serial = (int)Gmp.mpz(Standards.UUID.make_version1(-1)->encode(), 256); +  +  Sequence dn = Certificate.build_distinguished_name(name); +  +  void add(string name, Object data, void|int critical) +  { +  Identifier id = Identifiers.ce_ids[name]; +  if(!extensions[id]) +  extensions[id] = make_extension(id, data, critical); +  }; +  +  if(!extensions) extensions = ([]); +  // FIXME: authorityKeyIdentifier +  add("keyUsage", build_keyUsage(KU_digitalSignature|KU_keyEncipherment), 1); +  add("basicConstraints", Sequence(({Boolean(0)})), 1); +  return sign_key(dn, c, ca_key, h||Crypto.SHA256, ca->subject, serial, ttl, extensions); + } +  + string make_root_certificate(Crypto.Sign c, int ttl, +  mapping|array name, +  mapping(Identifier:Sequence)|void extensions, +  void|Crypto.Hash h, void|int serial) + { +  if(!serial) +  serial = (int)Gmp.mpz(Standards.UUID.make_version1(-1)->encode(), 256); +  +  Sequence dn = Certificate.build_distinguished_name(name); +  +  void add(string name, Object data, void|int critical) +  { +  Identifier id = Identifiers.ce_ids[name]; +  if(!extensions[id]) +  extensions[id] = make_extension(id, data, critical); +  }; +  +  if(!extensions) extensions = ([]); +  +  // While RFC 3280 section 4.2.1.2 suggest to only hash the BIT +  // STRING part of the subjectPublicKey, it is only a suggestion. +  // FIXME: authorityKeyIdentifier +  add("subjectKeyIdentifier", +  OctetString( Crypto.SHA1.hash(c->pkcs_public_key()->get_der()) )); +  add("keyUsage", build_keyUsage(KU_keyCertSign|KU_cRLSign), 1); +  add("basicConstraints", Sequence(({Boolean(1)})), 1); +  +  return sign_key(dn, c, c, h||Crypto.SHA256, dn, serial, ttl, extensions); + } +    //! Decodes a certificate and verifies that it is structually sound.   //! Returns a @[TBSCertificate] object if ok, otherwise @expr{0@}.   TBSCertificate decode_certificate(string|object cert)   {    if (stringp (cert)) {    cert = Standards.ASN1.Decode.simple_der_decode(cert, x509_types);    }       if (!cert    || (cert->type_name != "SEQUENCE")
pike.git/lib/modules/Standards.pmod/X509.pmod:1660:       if(idx == 0) // The root cert    {    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(!verifiers && require_trust)    ERROR(CERT_ROOT_UNTRUSTED);    +  if( !arrayp(verifiers) ) +  verifiers = ({ verifiers }); +     // 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(!verifiers)    verifiers = ({ tbs->public_key });    } else if (objectp(verifiers)) {