Example #1
0
/*
* Return information about the subject
*/
std::vector<std::string>
X509_Certificate::subject_info(const std::string& req) const
   {
   if(req == "Email")
      return this->subject_info("RFC822");

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

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

   // These will be removed later:
   if(req == "X509.Certificate.v2.key_id")
      return {hex_encode(this->v2_subject_key_id())};
   if(req == "X509v3.SubjectKeyIdentifier")
      return {hex_encode(this->subject_key_id())};
   if(req == "X509.Certificate.dn_bits")
      return {hex_encode(this->raw_subject_dn())};
   if(req == "X509.Certificate.start")
      return {not_before().to_string()};
   if(req == "X509.Certificate.end")
      return {not_after().to_string()};

   if(req == "X509.Certificate.version")
      return {std::to_string(x509_version())};
   if(req == "X509.Certificate.serial")
      return {hex_encode(serial_number())};

   return data().m_subject_ds.get(req);
   }
      Test::Result test_response_certificate_access()
         {
         Test::Result result("OCSP response certificate access");

         try
            {
            Botan::OCSP::Response resp1(Test::read_binary_data_file("x509/ocsp/resp1.der"));
            const auto &certs1 = resp1.certificates();
            if(result.test_eq("Expected count of certificates", certs1.size(), 1))
               {
               const auto cert = certs1.front();
               const Botan::X509_DN expected_dn({std::make_pair(
                  "X520.CommonName",
                  "Symantec Class 3 EV SSL CA - G3 OCSP Responder")});
               const bool matches = cert.subject_dn() == expected_dn;
               result.test_eq("CN matches expected", matches, true);
               }

            Botan::OCSP::Response resp2(Test::read_binary_data_file("x509/ocsp/resp2.der"));
            const auto &certs2 = resp2.certificates();
            result.test_eq("Expect no certificates", certs2.size(), 0);
            }
         catch(Botan::Exception& e)
            {
            result.test_failure("Parsing failed", e.what());
            }

         return result;
         }
Example #3
0
std::vector<X509_DN> Certificate_Store_MacOS::all_subjects() const
   {
   scoped_CFType<CFArrayRef> result(m_impl->search());

   if(!result)
      {
      return {};  // not a single certificate found in the keychain
      }

   const auto count = CFArrayGetCount(result.get());
   BOTAN_ASSERT(count > 0, "subject result list contains data");

   std::vector<X509_DN> output;
   output.reserve(count);
   for(unsigned int i = 0; i < count; ++i)
      {
      // Note: Apple's API provides SecCertificateCopyNormalizedSubjectSequence
      //       which would have saved us from reading a Botan::X509_Certificate,
      //       however, this function applies the same DN "normalization" as
      //       stated above.
      auto cfCert = to_SecCertificateRef(CFArrayGetValueAtIndex(result.get(), i));
      auto cert = readCertificate(cfCert);
      output.emplace_back(cert->subject_dn());
      }

   return output;
   }
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();
   }