summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp')
-rw-r--r--comm/third_party/botan/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp b/comm/third_party/botan/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp
new file mode 100644
index 0000000000..9804759b96
--- /dev/null
+++ b/comm/third_party/botan/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp
@@ -0,0 +1,148 @@
+/*
+* Certificate Store
+* (C) 1999-2019 Jack Lloyd
+* (C) 2019 Patrick Schmidt
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/certstor_flatfile.h>
+#include <botan/pkix_types.h>
+#include <botan/data_src.h>
+#include <botan/pem.h>
+#include <stdexcept>
+
+namespace Botan {
+namespace {
+std::vector<std::vector<uint8_t>> decode_all_certificates(DataSource& source)
+ {
+ std::vector<std::vector<uint8_t>> pems;
+
+ while(!source.end_of_data())
+ {
+ std::string label;
+ std::vector<uint8_t> cert;
+ try
+ {
+ cert = unlock(PEM_Code::decode(source, label));
+
+ if(label == "CERTIFICATE" || label == "X509 CERTIFICATE" || label == "TRUSTED CERTIFICATE")
+ {
+ pems.push_back(cert);
+ }
+ }
+ catch(const Decoding_Error&) {}
+ }
+
+ return pems;
+ }
+}
+
+Flatfile_Certificate_Store::Flatfile_Certificate_Store(const std::string& file, bool ignore_non_ca)
+ {
+ if(file.empty())
+ {
+ throw Invalid_Argument("Flatfile_Certificate_Store::Flatfile_Certificate_Store invalid file path");
+ }
+
+ DataSource_Stream file_stream(file);
+
+ for(const std::vector<uint8_t>& der : decode_all_certificates(file_stream))
+ {
+ std::shared_ptr<const X509_Certificate> cert = std::make_shared<const X509_Certificate>(der.data(), der.size());
+
+ /*
+ * Various weird or misconfigured system roots include intermediate certificates,
+ * or even stranger certificates which are not valid for cert issuance at all.
+ * Previously this code would error on such cases as an obvious misconfiguration,
+ * but we cannot fix the trust store. So instead just ignore any such certificate.
+ */
+ if(cert->is_self_signed() && cert->is_CA_cert())
+ {
+ m_all_subjects.push_back(cert->subject_dn());
+ m_dn_to_cert[cert->subject_dn()].push_back(cert);
+ m_pubkey_sha1_to_cert.emplace(cert->subject_public_key_bitstring_sha1(), cert);
+ m_subject_dn_sha256_to_cert.emplace(cert->raw_subject_dn_sha256(), cert);
+ }
+ else if(!ignore_non_ca)
+ {
+ throw Invalid_Argument("Flatfile_Certificate_Store received non CA cert " + cert->subject_dn().to_string());
+ }
+ }
+
+ if(m_all_subjects.empty())
+ {
+ throw Invalid_Argument("Flatfile_Certificate_Store::Flatfile_Certificate_Store cert file is empty");
+ }
+ }
+
+std::vector<X509_DN> Flatfile_Certificate_Store::all_subjects() const
+ {
+ return m_all_subjects;
+ }
+
+std::vector<std::shared_ptr<const X509_Certificate>> Flatfile_Certificate_Store::find_all_certs(
+ const X509_DN& subject_dn,
+ const std::vector<uint8_t>& key_id) const
+ {
+ std::vector<std::shared_ptr<const X509_Certificate>> found_certs;
+ try
+ {
+ const auto certs = m_dn_to_cert.at(subject_dn);
+
+ for(auto cert : certs)
+ {
+ if(key_id.empty() || key_id == cert->subject_key_id())
+ {
+ found_certs.push_back(cert);
+ }
+ }
+ }
+ catch(const std::out_of_range&)
+ {
+ return {};
+ }
+
+ return found_certs;
+ }
+
+std::shared_ptr<const X509_Certificate>
+Flatfile_Certificate_Store::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const
+ {
+ if(key_hash.size() != 20)
+ {
+ throw Invalid_Argument("Flatfile_Certificate_Store::find_cert_by_pubkey_sha1 invalid hash");
+ }
+
+ auto found_cert = m_pubkey_sha1_to_cert.find(key_hash);
+
+ if(found_cert != m_pubkey_sha1_to_cert.end())
+ {
+ return found_cert->second;
+ }
+
+ return nullptr;
+ }
+
+std::shared_ptr<const X509_Certificate>
+Flatfile_Certificate_Store::find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const
+ {
+ if(subject_hash.size() != 32)
+ { throw Invalid_Argument("Flatfile_Certificate_Store::find_cert_by_raw_subject_dn_sha256 invalid hash"); }
+
+ auto found_cert = m_subject_dn_sha256_to_cert.find(subject_hash);
+
+ if(found_cert != m_subject_dn_sha256_to_cert.end())
+ {
+ return found_cert->second;
+ }
+
+ return nullptr;
+ }
+
+std::shared_ptr<const X509_CRL> Flatfile_Certificate_Store::find_crl_for(const X509_Certificate& subject) const
+ {
+ BOTAN_UNUSED(subject);
+ return {};
+ }
+}