Repository: randombit/botan
Pull request #2461 (2020-11-07 00:18:31)

Remove Data_Store


Patch:
diff --git a/doc/deprecated.rst b/doc/deprecated.rst
index 4701640ab..565e51085 100644
--- a/doc/deprecated.rst
+++ b/doc/deprecated.rst
@@ -125,11 +125,6 @@ Other API deprecations
 - The TLS constructors taking ``std::function`` for callbacks. Instead
   use the ``TLS::Callbacks`` interface.
 
-- Using ``X509_Certificate::subject_info`` and ``issuer_info`` to access any
-  information that is not included in the DN or subject alternative name. Prefer
-  using the specific assessor functions for other data, eg instead of
-  ``cert.subject_info("X509.Certificate.serial")`` use ``cert.serial_number()``.
-
 - The ``Buffered_Computation`` base class. In a future release the
   class will be removed, and all of member functions instead declared
   directly on ``MessageAuthenticationCode`` and ``HashFunction``. So
diff --git a/doc/migration_guide.rst b/doc/migration_guide.rst
deleted file mode 100644
index b02caae80..000000000
--- a/doc/migration_guide.rst
+++ /dev/null
@@ -1,43 +0,0 @@
-Botan 2.x to 3.x Migration
-==============================
-
-This is a guide on migrating applications from Botan 2.x to 3.0.  If you find
-that some functionality you need has been removed in 3.0 please open an issue on
-Github - the goal is to remove only APIs where have a superior alternative
-exists or where the API is just hopelessly broken.
-
-Headers
---------
-
-Many headers have been removed from the public API.
-
-In some cases, such as ``datastor.h`` or ``tls_blocking.h``, the functionality
-presented was entirely deprecated, in which case it has been removed.
-
-In other cases (such as ``loadstor.h`` or ``rotate.h``) the header was really an
-implementation header of the library and not intended to be consumed as a public
-API. In these cases the header is still used internally, but not installed for
-application use.
-
-However in most cases there is a better way of performing the same operations,
-which usually works in both 2.x and 3.x. For example, in 3.0 all of the
-algorithm headers (such as ``aes.h``) have been removed. Instead you should
-create objects via the factory methods (in the case of AES,
-``BlockCipher::create``) which works in both 2.x and 3.0
-
-Algorithms Removed
--------------------
-
-The algorithms CAST-256, MISTY1, Kasumi, DESX, XTEA, PBKDF1, MCEIES, CBC-MAC and
-Tiger have been removed. The expectation is that literally nobody was using any
-of these algorithms for anything. All are obscure, and many are (more or less)
-broken.
-
-X.509 Certificate Info Access
--------------------------------
-
-Previously ``X509_Certificate::subject_info`` and ``issuer_info`` could be used
-to query information about extensions. This is not longer the case; instead you
-should either call a specific function on ``X509_Certificate`` which returns the
-same information, or lacking that, iterate over the result of
-``X509_Certificate::v3_extensions``.
diff --git a/src/lib/x509/datastor.cpp b/src/lib/x509/datastor.cpp
deleted file mode 100644
index 2fcd49a30..000000000
--- a/src/lib/x509/datastor.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
-* Data Store
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/datastor.h>
-#include <botan/exceptn.h>
-#include <botan/internal/parsing.h>
-#include <botan/hex.h>
-#include <botan/internal/stl_util.h>
-
-namespace Botan {
-
-/*
-* Data_Store Equality Comparison
-*/
-bool Data_Store::operator==(const Data_Store& other) const
-   {
-   return (m_contents == other.m_contents);
-   }
-
-/*
-* Check if this key has at least one value
-*/
-bool Data_Store::has_value(const std::string& key) const
-   {
-   return (m_contents.lower_bound(key) != m_contents.end());
-   }
-
-/*
-* Search based on an arbitrary predicate
-*/
-std::multimap<std::string, std::string> Data_Store::search_for(
-   std::function<bool (std::string, std::string)> predicate) const
-   {
-   std::multimap<std::string, std::string> out;
-
-   for(auto i = m_contents.begin(); i != m_contents.end(); ++i)
-      if(predicate(i->first, i->second))
-         out.insert(std::make_pair(i->first, i->second));
-
-   return out;
-   }
-
-/*
-* Search based on key equality
-*/
-std::vector<std::string> Data_Store::get(const std::string& looking_for) const
-   {
-   std::vector<std::string> out;
-   auto range = m_contents.equal_range(looking_for);
-   for(auto i = range.first; i != range.second; ++i)
-      out.push_back(i->second);
-   return out;
-   }
-
-/*
-* Get a single atom
-*/
-std::string Data_Store::get1(const std::string& key) const
-   {
-   std::vector<std::string> vals = get(key);
-
-   if(vals.empty())
-      throw Invalid_State("Data_Store::get1: No values set for " + key);
-   if(vals.size() > 1)
-      throw Invalid_State("Data_Store::get1: More than one value for " + key);
-
-   return vals[0];
-   }
-
-std::string Data_Store::get1(const std::string& key,
-                             const std::string& default_value) const
-   {
-   std::vector<std::string> vals = get(key);
-
-   if(vals.size() > 1)
-      throw Invalid_State("Data_Store::get1: More than one value for " + key);
-
-   if(vals.empty())
-      return default_value;
-
-   return vals[0];
-   }
-
-/*
-* Get a single std::vector atom
-*/
-std::vector<uint8_t>
-Data_Store::get1_memvec(const std::string& key) const
-   {
-   std::vector<std::string> vals = get(key);
-
-   if(vals.empty())
-      return std::vector<uint8_t>();
-
-   if(vals.size() > 1)
-      throw Invalid_State("Data_Store::get1_memvec: Multiple values for " +
-                          key);
-
-   return hex_decode(vals[0]);
-   }
-
-/*
-* Get a single uint32_t atom
-*/
-uint32_t Data_Store::get1_uint32(const std::string& key,
-                                 uint32_t default_val) const
-   {
-   std::vector<std::string> vals = get(key);
-
-   if(vals.empty())
-      return default_val;
-   else if(vals.size() > 1)
-      throw Invalid_State("Data_Store::get1_uint32: Multiple values for " + key);
-
-   return to_u32bit(vals[0]);
-   }
-
-/*
-* Insert a single key and value
-*/
-void Data_Store::add(const std::string& key, const std::string& val)
-   {
-   multimap_insert(m_contents, key, val);
-   }
-
-/*
-* Insert a single key and value
-*/
-void Data_Store::add(const std::string& key, uint32_t val)
-   {
-   add(key, std::to_string(val));
-   }
-
-/*
-* Insert a single key and value
-*/
-void Data_Store::add(const std::string& key, const secure_vector<uint8_t>& val)
-   {
-   add(key, hex_encode(val.data(), val.size()));
-   }
-
-void Data_Store::add(const std::string& key, const std::vector<uint8_t>& val)
-   {
-   add(key, hex_encode(val.data(), val.size()));
-   }
-
-/*
-* Insert a mapping of key/value pairs
-*/
-void Data_Store::add(const std::multimap<std::string, std::string>& in)
-   {
-   std::multimap<std::string, std::string>::const_iterator i = in.begin();
-   while(i != in.end())
-      {
-      m_contents.insert(*i);
-      ++i;
-      }
-   }
-
-/*
-* Create and populate a X509_DN
-*/
-X509_DN create_dn(const Data_Store& info)
-   {
-   auto names = info.search_for(
-      [](const std::string& key, const std::string&)
-      {
-         return (key.find("X520.") != std::string::npos);
-      });
-
-   X509_DN dn;
-
-   for(auto i = names.begin(); i != names.end(); ++i)
-      dn.add_attribute(i->first, i->second);
-
-   return dn;
-   }
-
-/*
-* Create and populate an AlternativeName
-*/
-AlternativeName create_alt_name(const Data_Store& info)
-   {
-   auto names = info.search_for(
-      [](const std::string& key, const std::string&)
-      {
-         return (key == "RFC822" ||
-                 key == "DNS" ||
-                 key == "URI" ||
-                 key == "IP");
-      });
-
-   AlternativeName alt_name;
-
-   for(auto i = names.begin(); i != names.end(); ++i)
-      alt_name.add_attribute(i->first, i->second);
-
-   return alt_name;
-   }
-
-}
diff --git a/src/lib/x509/datastor.h b/src/lib/x509/datastor.h
deleted file mode 100644
index d7e7aa99a..000000000
--- a/src/lib/x509/datastor.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-* Data Store
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_DATA_STORE_H_
-#define BOTAN_DATA_STORE_H_
-
-#include <botan/pkix_types.h>
-#include <functional>
-#include <string>
-#include <vector>
-#include <map>
-
-namespace Botan {
-
-/**
-* Data Store
-*
-* This class is used internally by the library, and exposed for ABI
-* reasons. There is no reason for applications to use this type directly.
-* It will be removed in a future major release.
-*/
-class BOTAN_UNSTABLE_API Data_Store final
-   {
-   public:
-      /**
-      * A search function
-      */
-      bool operator==(const Data_Store&) const;
-
-      std::multimap<std::string, std::string> search_for(
-         std::function<bool (std::string, std::string)> predicate) const;
-
-      std::vector<std::string> get(const std::string&) const;
-
-      std::string get1(const std::string& key) const;
-
-      std::string get1(const std::string& key,
-                       const std::string& default_value) const;
-
-      std::vector<uint8_t> get1_memvec(const std::string&) const;
-      uint32_t get1_uint32(const std::string&, uint32_t = 0) const;
-
-      bool has_value(const std::string&) const;
-
-      void add(const std::multimap<std::string, std::string>&);
-      void add(const std::string&, const std::string&);
-      void add(const std::string&, uint32_t);
-      void add(const std::string&, const secure_vector<uint8_t>&);
-      void add(const std::string&, const std::vector<uint8_t>&);
-   private:
-      std::multimap<std::string, std::string> m_contents;
-   };
-
-/*
-* Data Store Extraction Operations
-*/
-
-/*
-* Create and populate a X509_DN
-* @param info data store containing DN information
-* @return DN containing attributes from data store
-*/
-X509_DN
-BOTAN_DEPRECATED("Avoid roundtripping names through Data_Store")
-create_dn(const Data_Store& info);
-
-/*
-* Create and populate an AlternativeName
-* @param info data store containing AlternativeName information
-* @return AlternativeName containing attributes from data store
-*/
-AlternativeName
-BOTAN_DEPRECATED("Avoid roundtripping names through Data_Store")
-create_alt_name(const Data_Store& info);
-
-
-}
-
-#endif
diff --git a/src/lib/x509/info.txt b/src/lib/x509/info.txt
index 0c2ff8218..0e5e23ba7 100644
--- a/src/lib/x509/info.txt
+++ b/src/lib/x509/info.txt
@@ -25,7 +25,3 @@ x509cert.h
 x509path.h
 x509self.h
 </header:public>
-
-<header:internal>
-datastor.h
-</header:internal>
diff --git a/src/lib/x509/pkix_types.h b/src/lib/x509/pkix_types.h
index 983121955..74afb67f1 100644
--- a/src/lib/x509/pkix_types.h
+++ b/src/lib/x509/pkix_types.h
@@ -22,7 +22,6 @@
 namespace Botan {
 
 class X509_Certificate;
-class Data_Store;
 class Public_Key;
 
 /**
@@ -369,15 +368,6 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Extension
       */
       virtual Certificate_Extension* copy() const = 0;
 
-      /*
-      * Add the contents of this extension into the information
-      * for the subject and/or issuer, as necessary.
-      * @param subject the subject info
-      * @param issuer the issuer info
-      */
-      virtual void contents_to(Data_Store& subject,
-                               Data_Store& issuer) const = 0;
-
       /*
       * Callback visited during path validation.
       *
@@ -471,7 +461,6 @@ class BOTAN_PUBLIC_API(2,0) Extensions final : public ASN1_Object
 
       void encode_into(class DER_Encoder&) const override;
       void decode_from(class BER_Decoder&) override;
-      void contents_to(Data_Store&, Data_Store&) const;
 
       /**
       * Adds a new extension to the list.
diff --git a/src/lib/x509/x509_crl.h b/src/lib/x509/x509_crl.h
index 6d4a301ab..190baa819 100644
--- a/src/lib/x509/x509_crl.h
+++ b/src/lib/x509/x509_crl.h
@@ -152,7 +152,6 @@ class BOTAN_PUBLIC_API(2,0) X509_CRL final : public X509_Object
 
       /**
       * Get the CRL's distribution point
-      * @return CRL.IssuingDistributionPoint from the CRL's Data_Store
       */
       std::string crl_issuing_distribution_point() const;
 
diff --git a/src/lib/x509/x509_ext.cpp b/src/lib/x509/x509_ext.cpp
index c8eed6571..18fcaea44 100644
--- a/src/lib/x509/x509_ext.cpp
+++ b/src/lib/x509/x509_ext.cpp
@@ -9,7 +9,6 @@
 
 #include <botan/x509_ext.h>
 #include <botan/x509cert.h>
-#include <botan/internal/datastor.h>
 #include <botan/der_enc.h>
 #include <botan/ber_dec.h>
 #include <botan/hash.h>
@@ -295,20 +294,6 @@ void Extensions::decode_from(BER_Decoder& from_source)
    sequence.verify_end();
    }
 
-/*
-* Write the extensions to an info store
-*/
-void Extensions::contents_to(Data_Store& subject_info,
-                             Data_Store& issuer_info) const
-   {
-   for(auto&& m_extn_info : m_extension_info)
-      {
-      m_extn_info.second.obj().contents_to(subject_info, issuer_info);
-      subject_info.add(m_extn_info.second.obj().oid_name() + ".is_critical",
-                       m_extn_info.second.is_critical());
-      }
-   }
-
 namespace Cert_Extension {
 
 /*
@@ -353,15 +338,6 @@ void Basic_Constraints::decode_inner(const std::vector<uint8_t>& in)
       m_path_limit = 0;
    }
 
-/*
-* Return a textual representation
-*/
-void Basic_Constraints::contents_to(Data_Store& subject, Data_Store&) const
-   {
-   subject.add("X509v3.BasicConstraints.is_ca", (m_is_ca ? 1 : 0));
-   subject.add("X509v3.BasicConstraints.path_constraint", static_cast<uint32_t>(m_path_limit));
-   }
-
 /*
 * Encode the extension
 */
@@ -418,14 +394,6 @@ void Key_Usage::decode_inner(const std::vector<uint8_t>& in)
    m_constraints = Key_Constraints(usage);
    }
 
-/*
-* Return a textual representation
-*/
-void Key_Usage::contents_to(Data_Store& subject, Data_Store&) const
-   {
-   subject.add("X509v3.KeyUsage", m_constraints);
-   }
-
 /*
 * Encode the extension
 */
@@ -444,14 +412,6 @@ void Subject_Key_ID::decode_inner(const std::vector<uint8_t>& in)
    BER_Decoder(in).decode(m_key_id, OCTET_STRING).verify_end();
    }
 
-/*
-* Return a textual representation
-*/
-void Subject_Key_ID::contents_to(Data_Store& subject, Data_Store&) const
-   {
-   subject.add("X509v3.SubjectKeyIdentifier", m_key_id);
-   }
-
 /*
 * Subject_Key_ID Constructor
 */
@@ -493,15 +453,6 @@ void Authority_Key_ID::decode_inner(const std::vector<uint8_t>& in)
       .decode_optional_string(m_key_id, OCTET_STRING, 0);
    }
 
-/*
-* Return a textual representation
-*/
-void Authority_Key_ID::contents_to(Data_Store&, Data_Store& issuer) const
-   {
-   if(m_key_id.size())
-      issuer.add("X509v3.AuthorityKeyIdentifier", m_key_id);
-   }
-
 /*
 * Encode the extension
 */
@@ -538,23 +489,6 @@ void Issuer_Alternative_Name::decode_inner(const std::vector<uint8_t>& in)
    BER_Decoder(in).decode(m_alt_name);
    }
 
-/*
-* Return a textual representation
-*/
-void Subject_Alternative_Name::contents_to(Data_Store& subject_info,
-                                           Data_Store&) const
-   {
-   subject_info.add(get_alt_name().contents());
-   }
-
-/*
-* Return a textual representation
-*/
-void Issuer_Alternative_Name::contents_to(Data_Store&, Data_Store& issuer_info) const
-   {
-   issuer_info.add(get_alt_name().contents());
-   }
-
 /*
 * Encode the extension
 */
@@ -576,15 +510,6 @@ void Extended_Key_Usage::decode_inner(const std::vector<uint8_t>& in)
    BER_Decoder(in).decode_list(m_oids);
    }
 
-/*
-* Return a textual representation
-*/
-void Extended_Key_Usage::contents_to(Data_Store& subject, Data_Store&) const
-   {
-   for(size_t i = 0; i != m_oids.size(); ++i)
-      subject.add("X509v3.ExtendedKeyUsage", m_oids[i].to_string());
-   }
-
 /*
 * Encode the extension
 */
@@ -629,27 +554,6 @@ void Name_Constraints::decode_inner(const std::vector<uint8_t>& in)
    m_name_constraints = NameConstraints(std::move(permit),std::move(exclude));
    }
 
-/*
-* Return a textual representation
-*/
-void Name_Constraints::contents_to(Data_Store& subject, Data_Store&) const
-   {
-   std::stringstream ss;
-
-   for(const GeneralSubtree& gs: m_name_constraints.permitted())
-      {
-      ss << gs;
-      subject.add("X509v3.NameConstraints.permitted", ss.str());
-      ss.str(std::string());
-      }
-   for(const GeneralSubtree& gs: m_name_constraints.excluded())
-      {
-      ss << gs;
-      subject.add("X509v3.NameConstraints.excluded", ss.str());
-      ss.str(std::string());
-      }
-   }
-
 void Name_Constraints::validate(const X509_Certificate& subject, const X509_Certificate& issuer,
       const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path,
       std::vector<std::set<Certificate_Status_Code>>& cert_status,
@@ -780,15 +684,6 @@ void Certificate_Policies::decode_inner(const std::vector<uint8_t>& in)
       m_oids.push_back(policies[i].oid());
    }
 
-/*
-* Return a textual representation
-*/
-void Certificate_Policies::contents_to(Data_Store& info, Data_Store&) const
-   {
-   for(size_t i = 0; i != m_oids.size(); ++i)
-      info.add("X509v3.CertificatePolicies", m_oids[i].to_string());
-   }
-
 void Certificate_Policies::validate(
    const X509_Certificate& /*subject*/,
    const X509_Certificate& /*issuer*/,
@@ -852,14 +747,6 @@ void Authority_Information_Access::decode_inner(const std::vector<uint8_t>& in)
       }
    }
 
-void Authority_Information_Access::contents_to(Data_Store& subject, Data_Store&) const
-   {
-   if(!m_ocsp_responder.empty())
-      subject.add("OCSP.responder", m_ocsp_responder);
-   for(const std::string& ca_issuer : m_ca_issuers)
-      subject.add("PKIX.CertificateAuthorityIssuers", ca_issuer);
-   }
-
 /*
 * Checked accessor for the crl_number member
 */
@@ -899,14 +786,6 @@ void CRL_Number::decode_inner(const std::vector<uint8_t>& in)
    m_has_value = true;
    }
 
-/*
-* Return a textual representation
-*/
-void CRL_Number::contents_to(Data_Store& info, Data_Store&) const
-   {
-   info.add("X509v3.CRLNumber", static_cast<uint32_t>(m_crl_number));
-   }
-
 /*
 * Encode the extension
 */
@@ -927,14 +806,6 @@ void CRL_ReasonCode::decode_inner(const std::vector<uint8_t>& in)
    m_reason = static_cast<CRL_Code>(reason_code);
    }
 
-/*
-* Return a textual representation
-*/
-void CRL_ReasonCode::contents_to(Data_Store& info, Data_Store&) const
-   {
-   info.add("X509v3.CRLReasonCode", m_reason);
-   }
-
 std::vector<uint8_t> CRL_Distribution_Points::encode_inner() const
    {
    throw Not_Implemented("CRL_Distribution_Points encoding");
@@ -961,12 +832,6 @@ void CRL_Distribution_Points::decode_inner(const std::vector<uint8_t>& buf)
    m_crl_distribution_urls.push_back(ss.str());
    }
 
-void CRL_Distribution_Points::contents_to(Data_Store& subject, Data_Store&) const
-   {
-   for(const std::string& crl_url : m_crl_distribution_urls)
-      subject.add("CRL.DistributionPoint", crl_url);
-   }
-
 void CRL_Distribution_Points::Distribution_Point::encode_into(class DER_Encoder&) const
    {
    throw Not_Implemented("CRL_Distribution_Points encoding");
@@ -992,19 +857,6 @@ void CRL_Issuing_Distribution_Point::decode_inner(const std::vector<uint8_t>& bu
    BER_Decoder(buf).decode(m_distribution_point).verify_end();
    }
 
-void CRL_Issuing_Distribution_Point::contents_to(Data_Store& info, Data_Store&) const
-   {
-   auto contents = m_distribution_point.point().contents();
-   std::stringstream ss;
-
-   for(const auto& pair : contents)
-      {
-      ss << pair.first << ": " << pair.second << " ";
-      }
-
-   info.add("X509v3.CRLIssuingDistributionPoint", ss.str());
-   }
-
 std::vector<uint8_t> Unknown_Extension::encode_inner() const
    {
    return m_bytes;
@@ -1016,11 +868,6 @@ void Unknown_Extension::decode_inner(const std::vector<uint8_t>& bytes)
    m_bytes = bytes;
    }
 
-void Unknown_Extension::contents_to(Data_Store&, Data_Store&) const
-   {
-   // No information store
-   }
-
 }
 
 }
diff --git a/src/lib/x509/x509_ext.h b/src/lib/x509/x509_ext.h
index cb6e064c9..f761a2448 100644
--- a/src/lib/x509/x509_ext.h
+++ b/src/lib/x509/x509_ext.h
@@ -13,7 +13,6 @@
 
 namespace Botan {
 
-class Data_Store;
 class X509_Certificate;
 
 namespace Cert_Extension {
@@ -44,7 +43,6 @@ class BOTAN_PUBLIC_API(2,0) Basic_Constraints final : public Certificate_Extensi
 
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       bool m_is_ca;
       size_t m_path_limit;
@@ -72,7 +70,6 @@ class BOTAN_PUBLIC_API(2,0) Key_Usage final : public Certificate_Extension
          { return (m_constraints != NO_CONSTRAINTS); }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       Key_Constraints m_constraints;
    };
@@ -106,7 +103,6 @@ class BOTAN_PUBLIC_API(2,0) Subject_Key_ID final : public Certificate_Extension
       bool should_encode() const override { return (m_key_id.size() > 0); }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       std::vector<uint8_t> m_key_id;
    };
@@ -135,7 +131,6 @@ class BOTAN_PUBLIC_API(2,0) Authority_Key_ID final : public Certificate_Extensio
       bool should_encode() const override { return (m_key_id.size() > 0); }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       std::vector<uint8_t> m_key_id;
    };
@@ -163,7 +158,6 @@ class BOTAN_PUBLIC_API(2,4) Subject_Alternative_Name final : public Certificate_
       bool should_encode() const override { return m_alt_name.has_items(); }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       AlternativeName m_alt_name;
    };
@@ -191,7 +185,6 @@ class BOTAN_PUBLIC_API(2,0) Issuer_Alternative_Name final : public Certificate_E
       bool should_encode() const override { return m_alt_name.has_items(); }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       AlternativeName m_alt_name;
    };
@@ -219,7 +212,6 @@ class BOTAN_PUBLIC_API(2,0) Extended_Key_Usage final : public Certificate_Extens
       bool should_encode() const override { return (m_oids.size() > 0); }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       std::vector<OID> m_oids;
    };
@@ -253,7 +245,6 @@ class BOTAN_PUBLIC_API(2,0) Name_Constraints final : public Certificate_Extensio
       bool should_encode() const override { return true; }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       NameConstraints m_name_constraints;
    };
@@ -289,7 +280,6 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Policies final : public Certificate_Exte
       bool should_encode() const override { return (m_oids.size() > 0); }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       std::vector<OID> m_oids;
    };
@@ -323,7 +313,6 @@ class BOTAN_PUBLIC_API(2,0) Authority_Information_Access final : public Certific
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
 
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       std::string m_ocsp_responder;
       std::vector<std::string> m_ca_issuers;
@@ -351,7 +340,6 @@ class BOTAN_PUBLIC_API(2,0) CRL_Number final : public Certificate_Extension
       bool should_encode() const override { return m_has_value; }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       bool m_has_value;
       size_t m_crl_number;
@@ -379,7 +367,6 @@ class BOTAN_PUBLIC_API(2,0) CRL_ReasonCode final : public Certificate_Extension
       bool should_encode() const override { return (m_reason != UNSPECIFIED); }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       CRL_Code m_reason;
    };
@@ -428,7 +415,6 @@ class BOTAN_PUBLIC_API(2,0) CRL_Distribution_Points final : public Certificate_E
 
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       std::vector<Distribution_Point> m_distribution_points;
       std::vector<std::string> m_crl_distribution_urls;
@@ -462,7 +448,6 @@ class CRL_Issuing_Distribution_Point final : public Certificate_Extension
       bool should_encode() const override { return true; }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       CRL_Distribution_Points::Distribution_Point m_distribution_point;
    };
@@ -515,7 +500,6 @@ class BOTAN_PUBLIC_API(2,4) Unknown_Extension final : public Certificate_Extensi
       bool should_encode() const override { return true; }
       std::vector<uint8_t> encode_inner() const override;
       void decode_inner(const std::vector<uint8_t>&) override;
-      void contents_to(Data_Store&, Data_Store&) const override;
 
       OID m_oid;
       bool m_critical;
diff --git a/src/lib/x509/x509cert.cpp b/src/lib/x509/x509cert.cpp
index ee059bb61..c511dab4f 100644
--- a/src/lib/x509/x509cert.cpp
+++ b/src/lib/x509/x509cert.cpp
@@ -8,7 +8,6 @@
 
 #include <botan/x509cert.h>
 #include <botan/x509_key.h>
-#include <botan/internal/datastor.h>
 #include <botan/pk_keys.h>
 #include <botan/x509_ext.h>
 #include <botan/ber_dec.h>
@@ -61,9 +60,6 @@ struct X509_Certificate_Data
    AlternativeName m_issuer_alt_name;
    NameConstraints m_name_constraints;
 
-   Data_Store m_subject_ds;
-   Data_Store m_issuer_ds;
-
    size_t m_version = 0;
    size_t m_path_len_constraint = 0;
    Key_Constraints m_key_constraints = NO_CONSTRAINTS;
@@ -359,10 +355,6 @@ std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(const X509_Object& o
       data->m_fingerprint_sha256 = create_hex_fingerprint(full_encoding, "SHA-256");
       }
 
-   data->m_subject_ds.add(data->m_subject_dn.contents());
-   data->m_issuer_ds.add(data->m_issuer_dn.contents());
-   data->m_v3_extensions.contents_to(data->m_subject_ds, data->m_issuer_ds);
-
    return data;
    }
 
@@ -670,7 +662,7 @@ X509_Certificate::subject_info(const std::string& req) const
    if(req == "X509.Certificate.serial")
       return {hex_encode(serial_number())};
 
-   return data().m_subject_ds.get(req);
+   return {};
    }
 
 /*
@@ -693,7 +685,7 @@ X509_Certificate::issuer_info(const std::string& req) const
    if(req == "X509.Certificate.dn_bits")
       return {hex_encode(this->raw_issuer_dn())};
 
-   return data().m_issuer_ds.get(req);
+   return {};
    }
 
 /*
diff --git a/src/scripts/ci/travis.yml b/src/scripts/ci/travis.yml
index 903237924..64579c892 100644
--- a/src/scripts/ci/travis.yml
+++ b/src/scripts/ci/travis.yml
@@ -54,7 +54,6 @@ jobs:
 
     - name: iOS arm64 (XCode Clang)
       os: osx
-      osx_image: xcode12.2
       compiler: clang
       env:
        - TARGET="cross-arm64"


Test patch:
diff --git a/src/tests/test_datastore.cpp b/src/tests/test_datastore.cpp
deleted file mode 100644
index 3f2499abb..000000000
--- a/src/tests/test_datastore.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-* (C) 2018 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include "tests.h"
-
-#if defined(BOTAN_HAS_X509_CERTIFICATES)
-
-#include <botan/internal/datastor.h>
-
-namespace Botan_Tests {
-
-class Datastore_Tests : public Test
-   {
-   public:
-      std::vector<Test::Result> run() override
-         {
-         Test::Result result("Data_Store");
-
-         Botan::Data_Store ds1;
-         Botan::Data_Store ds2;
-
-         result.confirm("equality", ds1 == ds2);
-
-         result.test_eq("has_value", ds1.has_value("key"), false);
-         result.test_eq("get1 with default", ds1.get1("key", "default"), "default");
-
-         result.test_throws("get1", "Data_Store::get1: No values set for missing_key",
-                            [&ds1]() { ds1.get1("missing_key"); });
-
-         result.test_eq("search_for", ds1.search_for([](std::string, std::string) { return true; }).size(), 0);
-
-         ds1.add("key", "value");
-
-         result.test_eq("search_for", ds1.search_for([](std::string, std::string) { return true; }).size(), 1);
-
-         result.test_eq("equality", ds1 == ds2, false);
-
-         result.test_eq("has_value", ds1.has_value("key"), true);
-         result.test_eq("get1 with default", ds1.get1("key", "default"), "value");
-         result.test_eq("get1", ds1.get1("key"), "value");
-
-         result.test_eq("get1_memvec", ds1.get1_memvec("memvec").size(), 0);
-
-         const std::vector<uint8_t> memvec = { 9, 1, 1, 4 };
-         ds1.add("memvec", memvec);
-
-         result.test_eq("get1_memvec", ds1.get1_memvec("memvec"), memvec);
-
-         result.test_eq("get1_uint32", ds1.get1_uint32("memvec"), size_t(9010104));
-
-         result.test_eq("get1_uint32", ds1.get1_uint32("missing", 999), size_t(999));
-
-         ds1.add("key", "value2");
-
-         result.test_throws("get1", "Data_Store::get1: More than one value for key",
-                            [&ds1]() { ds1.get1("key"); });
-
-         result.test_eq("get multiple", ds1.get("key").size(), 2);
-
-         return {result};
-         }
-   };
-
-BOTAN_REGISTER_TEST("x509", "x509_datastore", Datastore_Tests);
-
-}
-
-#endif
diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp
index c4e1e2053..f6eceb768 100644
--- a/src/tests/unit_x509.cpp
+++ b/src/tests/unit_x509.cpp
@@ -1353,8 +1353,6 @@ class String_Extension final : public Botan::Certificate_Extension
          return "String Extension";
          }
 
-      void contents_to(Botan::Data_Store&, Botan::Data_Store&) const override {}
-
       std::vector<uint8_t> encode_inner() const override
          {
          std::vector<uint8_t> bits;