Repository: randombit/botan
Pull request #2683 (2021-04-03 14:32:10)

Avoid raw pointers for ownership transfers
GH #2677 

cc @lieser @securitykernel 


Patch:
diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h
index b98f20bc8..f24e2fce5 100644
--- a/src/lib/rng/rng.h
+++ b/src/lib/rng/rng.h
@@ -271,11 +271,19 @@ class BOTAN_PUBLIC_API(2,0) Serialized_RNG final : public RandomNumberGenerator
          m_rng->add_entropy(in, len);
          }
 
-      /*
+      /**
       * Since 2.16.0 this is no longer needed for any RNG type. This
       * class will be removed in a future major release.
       */
+      BOTAN_DEPRECATED("Use version accepting a unique_ptr")
       explicit Serialized_RNG(RandomNumberGenerator* rng) : m_rng(rng) {}
+
+      /**
+      * Since 2.16.0 this is no longer needed for any RNG type. This
+      * class will be removed in a future major release.
+      */
+      explicit Serialized_RNG(std::unique_ptr<RandomNumberGenerator> rng) : m_rng(std::move(rng)) {}
+
    private:
       mutable mutex_type m_mutex;
       std::unique_ptr<RandomNumberGenerator> m_rng;
diff --git a/src/lib/x509/crl_ent.cpp b/src/lib/x509/crl_ent.cpp
index f0abb9c82..138590f59 100644
--- a/src/lib/x509/crl_ent.cpp
+++ b/src/lib/x509/crl_ent.cpp
@@ -34,7 +34,7 @@ CRL_Entry::CRL_Entry(const X509_Certificate& cert, CRL_Code why)
 
    if(why != CRL_Code::UNSPECIFIED)
       {
-      m_data->m_extensions.add(new Cert_Extension::CRL_ReasonCode(why));
+      m_data->m_extensions.add(std::make_unique<Cert_Extension::CRL_ReasonCode>(why));
       }
    }
 
diff --git a/src/lib/x509/pkix_types.h b/src/lib/x509/pkix_types.h
index 00c58acb6..609c6c796 100644
--- a/src/lib/x509/pkix_types.h
+++ b/src/lib/x509/pkix_types.h
@@ -366,7 +366,8 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Extension
       * Make a copy of this extension
       * @return copy of this
       */
-      virtual Certificate_Extension* copy() const = 0;
+
+      virtual std::unique_ptr<Certificate_Extension> copy() const = 0;
 
       /*
       * Callback visited during path validation.
@@ -468,7 +469,7 @@ class BOTAN_PUBLIC_API(2,0) Extensions final : public ASN1_Object
       * @param critical whether this extension should be marked as critical
       * @throw Invalid_Argument if the extension is already present in the list
       */
-      void add(Certificate_Extension* extn, bool critical = false);
+      void add(std::unique_ptr<Certificate_Extension> extn, bool critical = false);
 
       /**
       * Adds a new extension to the list unless it already exists. If the extension
@@ -478,14 +479,14 @@ class BOTAN_PUBLIC_API(2,0) Extensions final : public ASN1_Object
       * @param critical whether this extension should be marked as critical
       * @return true if the object was added false if the extension was already used
       */
-      bool add_new(Certificate_Extension* extn, bool critical = false);
+      bool add_new(std::unique_ptr<Certificate_Extension> extn, bool critical = false);
 
       /**
       * Adds an extension to the list or replaces it.
       * @param extn the certificate extension
       * @param critical whether this extension should be marked as critical
       */
-      void replace(Certificate_Extension* extn, bool critical = false);
+      void replace(std::unique_ptr<Certificate_Extension> extn, bool critical = false);
 
       /**
       * Remove an extension from the list. Returns true if the
@@ -563,8 +564,8 @@ class BOTAN_PUBLIC_API(2,0) Extensions final : public ASN1_Object
          {
          public:
             Extensions_Info(bool critical,
-                            Certificate_Extension* ext) :
-               m_obj(ext),
+                            std::unique_ptr<Certificate_Extension> ext) :
+               m_obj(std::move(ext)),
                m_bits(m_obj->encode_inner()),
                m_critical(critical)
                {
@@ -572,8 +573,8 @@ class BOTAN_PUBLIC_API(2,0) Extensions final : public ASN1_Object
 
             Extensions_Info(bool critical,
                             const std::vector<uint8_t>& encoding,
-                            Certificate_Extension* ext) :
-               m_obj(ext),
+                            std::unique_ptr<Certificate_Extension> ext) :
+               m_obj(std::move(ext)),
                m_bits(encoding),
                m_critical(critical)
                {
diff --git a/src/lib/x509/x509_ca.cpp b/src/lib/x509/x509_ca.cpp
index 67e17be33..f5ceb70f7 100644
--- a/src/lib/x509/x509_ca.cpp
+++ b/src/lib/x509/x509_ca.cpp
@@ -93,22 +93,22 @@ Extensions choose_extensions(const PKCS10_Request& req,
    Extensions extensions = req.extensions();
 
    extensions.replace(
-      new Cert_Extension::Basic_Constraints(req.is_CA(), req.path_limit()),
+      std::make_unique<Cert_Extension::Basic_Constraints>(req.is_CA(), req.path_limit()),
       true);
 
    if(constraints != NO_CONSTRAINTS)
       {
-      extensions.replace(new Cert_Extension::Key_Usage(constraints), true);
+      extensions.replace(std::make_unique<Cert_Extension::Key_Usage>(constraints), true);
       }
 
-   extensions.replace(new Cert_Extension::Authority_Key_ID(ca_cert.subject_key_id()));
-   extensions.replace(new Cert_Extension::Subject_Key_ID(req.raw_public_key(), hash_fn));
+   extensions.replace(std::make_unique<Cert_Extension::Authority_Key_ID>(ca_cert.subject_key_id()));
+   extensions.replace(std::make_unique<Cert_Extension::Subject_Key_ID>(req.raw_public_key(), hash_fn));
 
    extensions.replace(
-      new Cert_Extension::Subject_Alternative_Name(req.subject_alt_name()));
+      std::make_unique<Cert_Extension::Subject_Alternative_Name>(req.subject_alt_name()));
 
    extensions.replace(
-      new Cert_Extension::Extended_Key_Usage(req.ex_constraints()));
+      std::make_unique<Cert_Extension::Extended_Key_Usage>(req.ex_constraints()));
 
    return extensions;
    }
@@ -273,8 +273,8 @@ X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked,
    auto expire_time = issue_time + next_update;
 
    Extensions extensions;
-   extensions.add(new Cert_Extension::Authority_Key_ID(m_ca_cert.subject_key_id()));
-   extensions.add(new Cert_Extension::CRL_Number(crl_number));
+   extensions.add(std::make_unique<Cert_Extension::Authority_Key_ID>(m_ca_cert.subject_key_id()));
+   extensions.add(std::make_unique<Cert_Extension::CRL_Number>(crl_number));
 
    // clang-format off
    const std::vector<uint8_t> crl = X509_Object::make_signed(
diff --git a/src/lib/x509/x509_ext.cpp b/src/lib/x509/x509_ext.cpp
index 6f7994497..3759a9fbd 100644
--- a/src/lib/x509/x509_ext.cpp
+++ b/src/lib/x509/x509_ext.cpp
@@ -119,32 +119,30 @@ void Certificate_Extension::validate(const X509_Certificate&, const X509_Certifi
 /*
 * Add a new cert
 */
-void Extensions::add(Certificate_Extension* extn, bool critical)
+void Extensions::add(std::unique_ptr<Certificate_Extension> extn, bool critical)
    {
    // sanity check: we don't want to have the same extension more than once
    if(m_extension_info.count(extn->oid_of()) > 0)
       {
       const std::string name = extn->oid_name();
-      delete extn;
       throw Invalid_Argument("Extension " + name + " already present in Extensions::add");
       }
 
    const OID oid = extn->oid_of();
-   Extensions_Info info(critical, extn);
+   Extensions_Info info(critical, std::move(extn));
    m_extension_oids.push_back(oid);
    m_extension_info.emplace(oid, info);
    }
 
-bool Extensions::add_new(Certificate_Extension* extn, bool critical)
+bool Extensions::add_new(std::unique_ptr<Certificate_Extension> extn, bool critical)
    {
    if(m_extension_info.count(extn->oid_of()) > 0)
       {
-      delete extn;
       return false; // already exists
       }
 
    const OID oid = extn->oid_of();
-   Extensions_Info info(critical, extn);
+   Extensions_Info info(critical, std::move(extn));
    m_extension_oids.push_back(oid);
    m_extension_info.emplace(oid, info);
    return true;
@@ -162,13 +160,13 @@ bool Extensions::remove(const OID& oid)
    return erased;
    }
 
-void Extensions::replace(Certificate_Extension* extn, bool critical)
+void Extensions::replace(std::unique_ptr<Certificate_Extension> extn, bool critical)
    {
    // Remove it if it existed
    remove(extn->oid_of());
 
    const OID oid = extn->oid_of();
-   Extensions_Info info(critical, extn);
+   Extensions_Info info(critical, std::move(extn));
    m_extension_oids.push_back(oid);
    m_extension_info.emplace(oid, info);
    }
@@ -208,7 +206,7 @@ std::unique_ptr<Certificate_Extension> Extensions::get(const OID& oid) const
    {
    if(const Certificate_Extension* ext = this->get_extension_object(oid))
       {
-      return std::unique_ptr<Certificate_Extension>(ext->copy());
+      return ext->copy();
       }
    return nullptr;
    }
@@ -220,7 +218,7 @@ std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> Extensions:
       {
       exts.push_back(
          std::make_pair(
-            std::unique_ptr<Certificate_Extension>(ext.second.obj().copy()),
+            ext.second.obj().copy(),
             ext.second.is_critical())
          );
       }
@@ -286,7 +284,7 @@ void Extensions::decode_from(BER_Decoder& from_source)
       .end_cons();
 
       std::unique_ptr<Certificate_Extension> obj = create_extn_obj(oid, critical, bits);
-      Extensions_Info info(critical, bits, obj.release());
+      Extensions_Info info(critical, bits, std::move(obj));
 
       m_extension_oids.push_back(oid);
       m_extension_info.emplace(oid, info);
@@ -760,11 +758,11 @@ size_t CRL_Number::get_crl_number() const
 /*
 * Copy a CRL_Number extension
 */
-CRL_Number* CRL_Number::copy() const
+std::unique_ptr<Certificate_Extension> CRL_Number::copy() const
    {
    if(!m_has_value)
       throw Invalid_State("CRL_Number::copy: Not set");
-   return new CRL_Number(m_crl_number);
+   return std::make_unique<CRL_Number>(m_crl_number);
    }
 
 /*
diff --git a/src/lib/x509/x509_ext.h b/src/lib/x509/x509_ext.h
index aa26c59fd..54b240881 100644
--- a/src/lib/x509/x509_ext.h
+++ b/src/lib/x509/x509_ext.h
@@ -25,8 +25,8 @@ static const size_t NO_CERT_PATH_LIMIT = 0xFFFFFFF0;
 class BOTAN_PUBLIC_API(2,0) Basic_Constraints final : public Certificate_Extension
    {
    public:
-      Basic_Constraints* copy() const override
-         { return new Basic_Constraints(m_is_ca, m_path_limit); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<Basic_Constraints>(m_is_ca, m_path_limit); }
 
       Basic_Constraints(bool ca = false, size_t limit = 0) :
          m_is_ca(ca), m_path_limit(limit) {}
@@ -54,7 +54,10 @@ class BOTAN_PUBLIC_API(2,0) Basic_Constraints final : public Certificate_Extensi
 class BOTAN_PUBLIC_API(2,0) Key_Usage final : public Certificate_Extension
    {
    public:
-      Key_Usage* copy() const override { return new Key_Usage(m_constraints); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         {
+         return std::make_unique<Key_Usage>(m_constraints);
+         }
 
       explicit Key_Usage(Key_Constraints c = NO_CONSTRAINTS) : m_constraints(c) {}
 
@@ -87,8 +90,8 @@ class BOTAN_PUBLIC_API(2,0) Subject_Key_ID final : public Certificate_Extension
       Subject_Key_ID(const std::vector<uint8_t>& public_key,
                      const std::string& hash_fn);
 
-      Subject_Key_ID* copy() const override
-         { return new Subject_Key_ID(m_key_id); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<Subject_Key_ID>(m_key_id); }
 
       const std::vector<uint8_t>& get_key_id() const { return m_key_id; }
 
@@ -113,8 +116,8 @@ class BOTAN_PUBLIC_API(2,0) Subject_Key_ID final : public Certificate_Extension
 class BOTAN_PUBLIC_API(2,0) Authority_Key_ID final : public Certificate_Extension
    {
    public:
-      Authority_Key_ID* copy() const override
-         { return new Authority_Key_ID(m_key_id); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<Authority_Key_ID>(m_key_id); }
 
       Authority_Key_ID() = default;
       explicit Authority_Key_ID(const std::vector<uint8_t>& k) : m_key_id(k) {}
@@ -146,8 +149,8 @@ class BOTAN_PUBLIC_API(2,4) Subject_Alternative_Name final : public Certificate_
       static OID static_oid() { return OID("2.5.29.17"); }
       OID oid_of() const override { return static_oid(); }
 
-      Subject_Alternative_Name* copy() const override
-         { return new Subject_Alternative_Name(get_alt_name()); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<Subject_Alternative_Name>(get_alt_name()); }
 
       explicit Subject_Alternative_Name(const AlternativeName& name = AlternativeName()) :
          m_alt_name(name) {}
@@ -173,8 +176,8 @@ class BOTAN_PUBLIC_API(2,0) Issuer_Alternative_Name final : public Certificate_E
       static OID static_oid() { return OID("2.5.29.18"); }
       OID oid_of() const override { return static_oid(); }
 
-      Issuer_Alternative_Name* copy() const override
-         { return new Issuer_Alternative_Name(get_alt_name()); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<Issuer_Alternative_Name>(get_alt_name()); }
 
       explicit Issuer_Alternative_Name(const AlternativeName& name = AlternativeName()) :
          m_alt_name(name) {}
@@ -195,8 +198,8 @@ class BOTAN_PUBLIC_API(2,0) Issuer_Alternative_Name final : public Certificate_E
 class BOTAN_PUBLIC_API(2,0) Extended_Key_Usage final : public Certificate_Extension
    {
    public:
-      Extended_Key_Usage* copy() const override
-         { return new Extended_Key_Usage(m_oids); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<Extended_Key_Usage>(m_oids); }
 
       Extended_Key_Usage() = default;
       explicit Extended_Key_Usage(const std::vector<OID>& o) : m_oids(o) {}
@@ -222,8 +225,8 @@ class BOTAN_PUBLIC_API(2,0) Extended_Key_Usage final : public Certificate_Extens
 class BOTAN_PUBLIC_API(2,0) Name_Constraints final : public Certificate_Extension
    {
    public:
-      Name_Constraints* copy() const override
-         { return new Name_Constraints(m_name_constraints); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<Name_Constraints>(m_name_constraints); }
 
       Name_Constraints() = default;
       Name_Constraints(const NameConstraints &nc) : m_name_constraints(nc) {}
@@ -255,8 +258,8 @@ class BOTAN_PUBLIC_API(2,0) Name_Constraints final : public Certificate_Extensio
 class BOTAN_PUBLIC_API(2,0) Certificate_Policies final : public Certificate_Extension
    {
    public:
-      Certificate_Policies* copy() const override
-         { return new Certificate_Policies(m_oids); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<Certificate_Policies>(m_oids); }
 
       Certificate_Policies() = default;
       explicit Certificate_Policies(const std::vector<OID>& o) : m_oids(o) {}
@@ -287,8 +290,8 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Policies final : public Certificate_Exte
 class BOTAN_PUBLIC_API(2,0) Authority_Information_Access final : public Certificate_Extension
    {
    public:
-      Authority_Information_Access* copy() const override
-         { return new Authority_Information_Access(m_ocsp_responder, m_ca_issuers); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<Authority_Information_Access>(m_ocsp_responder, m_ca_issuers); }
 
       Authority_Information_Access() = default;
 
@@ -321,7 +324,7 @@ class BOTAN_PUBLIC_API(2,0) Authority_Information_Access final : public Certific
 class BOTAN_PUBLIC_API(2,0) CRL_Number final : public Certificate_Extension
    {
    public:
-      CRL_Number* copy() const override;
+      std::unique_ptr<Certificate_Extension> copy() const override;
 
       CRL_Number() : m_has_value(false), m_crl_number(0) {}
       CRL_Number(size_t n) : m_has_value(true), m_crl_number(n) {}
@@ -348,8 +351,8 @@ class BOTAN_PUBLIC_API(2,0) CRL_Number final : public Certificate_Extension
 class BOTAN_PUBLIC_API(2,0) CRL_ReasonCode final : public Certificate_Extension
    {
    public:
-      CRL_ReasonCode* copy() const override
-         { return new CRL_ReasonCode(m_reason); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<CRL_ReasonCode>(m_reason); }
 
       explicit CRL_ReasonCode(CRL_Code r = CRL_Code::UNSPECIFIED) : m_reason(r) {}
 
@@ -386,8 +389,8 @@ class BOTAN_PUBLIC_API(2,0) CRL_Distribution_Points final : public Certificate_E
             AlternativeName m_point;
          };
 
-      CRL_Distribution_Points* copy() const override
-         { return new CRL_Distribution_Points(m_distribution_points); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<CRL_Distribution_Points>(m_distribution_points); }
 
       CRL_Distribution_Points() = default;
 
@@ -429,8 +432,8 @@ class CRL_Issuing_Distribution_Point final : public Certificate_Extension
       explicit CRL_Issuing_Distribution_Point(const CRL_Distribution_Points::Distribution_Point& distribution_point) :
          m_distribution_point(distribution_point) {}
 
-      CRL_Issuing_Distribution_Point* copy() const override
-         { return new CRL_Issuing_Distribution_Point(m_distribution_point); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<CRL_Issuing_Distribution_Point>(m_distribution_point); }
 
       const AlternativeName& get_point() const
          { return m_distribution_point.point(); }
@@ -459,8 +462,8 @@ class BOTAN_PUBLIC_API(2,4) Unknown_Extension final : public Certificate_Extensi
       Unknown_Extension(const OID& oid, bool critical) :
          m_oid(oid), m_critical(critical) {}
 
-      Unknown_Extension* copy() const override
-         { return new Unknown_Extension(m_oid, m_critical); }
+      std::unique_ptr<Certificate_Extension> copy() const override
+         { return std::make_unique<Unknown_Extension>(m_oid, m_critical); }
 
       /**
       * Return the OID of this unknown extension
@@ -503,7 +506,7 @@ class BOTAN_PUBLIC_API(2,4) Unknown_Extension final : public Certificate_Extensi
       std::vector<uint8_t> m_bytes;
    };
 
-   }
+}
 
 }
 
diff --git a/src/lib/x509/x509self.cpp b/src/lib/x509/x509self.cpp
index a4f2012fd..ad43055c4 100644
--- a/src/lib/x509/x509self.cpp
+++ b/src/lib/x509/x509self.cpp
@@ -79,24 +79,24 @@ X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts,
       }
 
    extensions.add_new(
-      new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit),
+      std::make_unique<Cert_Extension::Basic_Constraints>(opts.is_CA, opts.path_limit),
       true);
 
    if(constraints != NO_CONSTRAINTS)
       {
-      extensions.add_new(new Cert_Extension::Key_Usage(constraints), true);
+      extensions.add_new(std::make_unique<Cert_Extension::Key_Usage>(constraints), true);
       }
 
-   std::unique_ptr<Cert_Extension::Subject_Key_ID> skid(new Cert_Extension::Subject_Key_ID(pub_key, hash_fn));
+   std::unique_ptr<Cert_Extension::Subject_Key_ID> skid(std::make_unique<Cert_Extension::Subject_Key_ID>(pub_key, hash_fn));
 
-   extensions.add_new(new Cert_Extension::Authority_Key_ID(skid->get_key_id()));
-   extensions.add_new(skid.release());
+   extensions.add_new(std::make_unique<Cert_Extension::Authority_Key_ID>(skid->get_key_id()));
+   extensions.add_new(std::move(skid));
 
    extensions.add_new(
-      new Cert_Extension::Subject_Alternative_Name(subject_alt));
+      std::make_unique<Cert_Extension::Subject_Alternative_Name>(subject_alt));
 
    extensions.add_new(
-      new Cert_Extension::Extended_Key_Usage(opts.ex_constraints));
+      std::make_unique<Cert_Extension::Extended_Key_Usage>(opts.ex_constraints));
 
    return X509_CA::make_cert(signer.get(), rng, sig_algo, pub_key,
                              opts.start, opts.end,
@@ -129,14 +129,14 @@ PKCS10_Request create_cert_req(const X509_Cert_Options& opts,
 
    Extensions extensions = opts.extensions;
 
-   extensions.add_new(new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit));
+   extensions.add_new(std::make_unique<Cert_Extension::Basic_Constraints>(opts.is_CA, opts.path_limit));
 
    if(constraints != NO_CONSTRAINTS)
       {
-      extensions.add_new(new Cert_Extension::Key_Usage(constraints));
+      extensions.add_new(std::make_unique<Cert_Extension::Key_Usage>(constraints));
       }
-   extensions.add_new(new Cert_Extension::Extended_Key_Usage(opts.ex_constraints));
-   extensions.add_new(new Cert_Extension::Subject_Alternative_Name(subject_alt));
+   extensions.add_new(std::make_unique<Cert_Extension::Extended_Key_Usage>(opts.ex_constraints));
+   extensions.add_new(std::make_unique<Cert_Extension::Subject_Alternative_Name>(subject_alt));
 
    return PKCS10_Request::create(key,
                                  subject_dn,


Test patch:
diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp
index e9a38c223..8703abb93 100644
--- a/src/tests/unit_x509.cpp
+++ b/src/tests/unit_x509.cpp
@@ -211,7 +211,7 @@ Test::Result test_x509_extension()
    const auto oid_bc = Botan::OID::from_string("X509v3.BasicConstraints");
    const auto oid_skid = Botan::OID::from_string("X509v3.SubjectKeyIdentifier");
 
-   extn.add(new Botan::Cert_Extension::Basic_Constraints(true), true);
+   extn.add(std::make_unique<Botan::Cert_Extension::Basic_Constraints>(true), true);
 
    result.confirm("Basic constraints is set", extn.extension_set(oid_bc));
    result.confirm("Basic constraints is critical", extn.critical_extension_set(oid_bc));
@@ -225,17 +225,17 @@ Test::Result test_x509_extension()
                       [&]() { extn.get_extension_bits(oid_skid); });
 
    result.test_throws("Extension::add throws on second add",
-                      [&]() { extn.add(new Botan::Cert_Extension::Basic_Constraints(false), false); });
+                      [&]() { extn.add(std::make_unique<Botan::Cert_Extension::Basic_Constraints>(false), false); });
 
    result.test_eq("Extension::get_extension_bits",
                   extn.get_extension_bits(oid_bc), "30060101FF020100");
 
    result.confirm("Returns false since extension already existed",
-                  !extn.add_new(new Botan::Cert_Extension::Basic_Constraints(false), false));
+                  !extn.add_new(std::make_unique<Botan::Cert_Extension::Basic_Constraints>(false), false));
 
    result.confirm("Basic constraints is still critical", extn.critical_extension_set(oid_bc));
 
-   extn.replace(new Botan::Cert_Extension::Basic_Constraints(false), false);
+   extn.replace(std::make_unique<Botan::Cert_Extension::Basic_Constraints>(false), false);
    result.confirm("Replaced basic constraints is not critical", !extn.critical_extension_set(oid_bc));
    result.test_eq("Extension::get_extension_bits", extn.get_extension_bits(oid_bc), "3000");
 
@@ -781,7 +781,7 @@ Test::Result test_pkcs10_ext(const Botan::Private_Key& key,
    alt_name.add_attribute("DNS", "example.com");
    alt_name.add_attribute("DNS", "example.net");
 
-   opts.extensions.add(new Botan::Cert_Extension::Subject_Alternative_Name(alt_name));
+   opts.extensions.add(std::make_unique<Botan::Cert_Extension::Subject_Alternative_Name>(alt_name));
 
    Botan::PKCS10_Request req = Botan::X509::create_cert_req(opts, key, hash_fn, Test::rng());
 
@@ -1371,9 +1371,9 @@ class String_Extension final : public Botan::Certificate_Extension
          return m_contents;
          }
 
-      String_Extension* copy() const override
+      std::unique_ptr<Certificate_Extension> copy() const override
          {
-         return new String_Extension(m_contents);
+         return std::make_unique<String_Extension>(m_contents);
          }
 
       Botan::OID oid_of() const override
@@ -1501,7 +1501,7 @@ Test::Result test_x509_extensions(const Botan::Private_Key& ca_key,
    Botan::Extensions req_extensions;
    const Botan::OID oid("1.2.3.4.5.6.7.8.9.1");
    const Botan::OID ku_oid = Botan::OID::from_string("X509v3.KeyUsage");
-   req_extensions.add(new String_Extension("AAAAAAAAAAAAAABCDEF"), false);
+   req_extensions.add(std::make_unique<String_Extension>("AAAAAAAAAAAAAABCDEF"), false);
    opts.extensions = req_extensions;
    opts.set_padding_scheme(sig_padding);