Example #1
0
/*
* Return information about the issuer
*/
std::vector<std::string>
X509_Certificate::issuer_info(const std::string& req) const
   {
   if(issuer_dn().has_field(req))
      return issuer_dn().get_attribute(req);

   if(issuer_alt_name().has_field(req))
      return issuer_alt_name().get_attribute(req);

   // These will be removed later:
   if(req == "X509.Certificate.v2.key_id")
      return {hex_encode(this->v2_issuer_key_id())};
   if(req == "X509v3.AuthorityKeyIdentifier")
      return {hex_encode(this->authority_key_id())};
   if(req == "X509.Certificate.dn_bits")
      return {hex_encode(this->raw_issuer_dn())};

   return data().m_issuer_ds.get(req);
   }
Example #2
0
std::vector<X509_CRL> Certificate_Store_In_SQL::generate_crls() const
   {
   auto stmt = m_database->new_statement(
         "SELECT certificate,reason,time FROM " + m_prefix + "revoked "
         "JOIN " + m_prefix + "certificates ON " +
         m_prefix + "certificates.fingerprint == " + m_prefix + "revoked.fingerprint");

   std::map<X509_DN,std::vector<CRL_Entry>> crls;
   while(stmt->step())
      {
      auto blob = stmt->get_blob(0);
      auto cert = X509_Certificate(
            std::vector<uint8_t>(blob.first,blob.first + blob.second));
      auto code = static_cast<CRL_Code>(stmt->get_size_t(1));
      auto ent = CRL_Entry(cert,code);

      auto i = crls.find(cert.issuer_dn());
      if(i == crls.end())
         {
         crls.insert(std::make_pair(cert.issuer_dn(),std::vector<CRL_Entry>({ent})));
         }
      else
         {
         i->second.push_back(ent);
         }
      }

   std::vector<X509_CRL> ret;
   X509_Time t(std::chrono::system_clock::now());

   for(auto p: crls)
      {
      ret.push_back(X509_CRL(p.first,t,t,p.second));
      }

   return ret;
   }
Example #3
0
/**
* Check if this particular certificate is listed in the CRL
*/
bool X509_CRL::is_revoked(const X509_Certificate& cert) const
   {
   /*
   If the cert wasn't issued by the CRL issuer, it's possible the cert
   is revoked, but not by this CRL. Maybe throw an exception instead?
   */
   if(cert.issuer_dn() != issuer_dn())
      return false;

   std::vector<uint8_t> crl_akid = authority_key_id();
   std::vector<uint8_t> cert_akid = cert.authority_key_id();

   if(!crl_akid.empty() && !cert_akid.empty())
      {
      if(crl_akid != cert_akid)
         return false;
      }

   std::vector<uint8_t> cert_serial = cert.serial_number();

   bool is_revoked = false;

   // FIXME would be nice to avoid a linear scan here - maybe sort the entries?
   for(const CRL_Entry& entry : get_revoked())
      {
      if(cert_serial == entry.serial_number())
         {
         if(entry.reason_code() == REMOVE_FROM_CRL)
            is_revoked = false;
         else
            is_revoked = true;
         }
      }

   return is_revoked;
   }
Example #4
0
std::string X509_Certificate::to_string() const
   {
   std::ostringstream out;

   out << "Version: " << this->x509_version() << "\n";
   out << "Subject: " << subject_dn() << "\n";
   out << "Issuer: " << issuer_dn() << "\n";
   out << "Issued: " << this->not_before().readable_string() << "\n";
   out << "Expires: " << this->not_after().readable_string() << "\n";

   out << "Constraints:\n";
   Key_Constraints constraints = this->constraints();
   if(constraints == NO_CONSTRAINTS)
      out << " None\n";
   else
      {
      if(constraints & DIGITAL_SIGNATURE)
         out << "   Digital Signature\n";
      if(constraints & NON_REPUDIATION)
         out << "   Non-Repudiation\n";
      if(constraints & KEY_ENCIPHERMENT)
         out << "   Key Encipherment\n";
      if(constraints & DATA_ENCIPHERMENT)
         out << "   Data Encipherment\n";
      if(constraints & KEY_AGREEMENT)
         out << "   Key Agreement\n";
      if(constraints & KEY_CERT_SIGN)
         out << "   Cert Sign\n";
      if(constraints & CRL_SIGN)
         out << "   CRL Sign\n";
      if(constraints & ENCIPHER_ONLY)
         out << "   Encipher Only\n";
      if(constraints & DECIPHER_ONLY)
         out << "   Decipher Only\n";
      }

   const std::vector<OID> policies = this->certificate_policy_oids();
   if(!policies.empty())
      {
      out << "Policies: " << "\n";
      for(auto oid : policies)
         out << "   " << oid.as_string() << "\n";
      }

   std::vector<OID> ex_constraints = this->extended_key_usage();
   if(!ex_constraints.empty())
      {
      out << "Extended Constraints:\n";
      for(size_t i = 0; i != ex_constraints.size(); i++)
         out << "   " << OIDS::oid2str(ex_constraints[i]) << "\n";
      }

   const NameConstraints& name_constraints = this->name_constraints();

   if(!name_constraints.permitted().empty() || !name_constraints.excluded().empty())
      {
      out << "Name Constraints:\n";

      if(!name_constraints.permitted().empty())
         {
         out << "   Permit";
         for(auto st: name_constraints.permitted())
            {
            out << " " << st.base();
            }
         out << "\n";
         }

      if(!name_constraints.excluded().empty())
         {
         out << "   Exclude";
         for(auto st: name_constraints.excluded())
            {
            out << " " << st.base();
            }
         out << "\n";
         }
      }

   if(!ocsp_responder().empty())
      out << "OCSP responder " << ocsp_responder() << "\n";

   std::vector<std::string> ca_issuers = this->ca_issuers();
   if(!ca_issuers.empty())
      {
      out << "CA Issuers:\n";
      for(size_t i = 0; i != ca_issuers.size(); i++)
         out << "   URI: " << ca_issuers[i] << "\n";
      }

   if(!crl_distribution_point().empty())
      out << "CRL " << crl_distribution_point() << "\n";

   out << "Signature algorithm: " <<
      OIDS::oid2str(this->signature_algorithm().get_oid()) << "\n";

   out << "Serial number: " << hex_encode(this->serial_number()) << "\n";

   if(this->authority_key_id().size())
     out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n";

   if(this->subject_key_id().size())
     out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n";

   try
      {
      std::unique_ptr<Public_Key> pubkey(this->subject_public_key());
      out << "Public Key [" << pubkey->algo_name() << "-" << pubkey->key_length() << "]\n\n";
      out << X509::PEM_encode(*pubkey);
      }
   catch(Decoding_Error&)
      {
      const AlgorithmIdentifier& alg_id = this->subject_public_key_algo();
      out << "Failed to decode key with oid " << alg_id.get_oid().as_string() << "\n";
      }

   return out.str();
   }