Migrate EVP_PKEY to RefCounted.

Bug: 42290295
Change-Id: I3c9de2d93776e54e4fb6615784de3ff56a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/88888
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Xiangfei Ding <xfding@google.com>
Reviewed-by: Xiangfei Ding <xfding@google.com>
diff --git a/crypto/evp/evp.cc b/crypto/evp/evp.cc
index 5eca989..0f22a15 100644
--- a/crypto/evp/evp.cc
+++ b/crypto/evp/evp.cc
@@ -37,22 +37,11 @@
 // directory.
 OPENSSL_DECLARE_ERROR_REASON(EVP, EMPTY_PSK)
 
-EVP_PKEY *EVP_PKEY_new() {
-  EvpPkey *ret = NewZeroed<EvpPkey>();
-  if (ret == nullptr) {
-    return nullptr;
-  }
+EVP_PKEY *EVP_PKEY_new() { return New<EvpPkey>(); }
 
-  ret->references = 1;
-  return ret;
-}
+EvpPkey::EvpPkey() : RefCounted(CheckSubClass()) {}
 
-EvpPkey::~EvpPkey() {
-  // Refcount can be 1 if called by UniquePtr and 0 if called by EVP_PKEY_free.
-  BSSL_CHECK(references.load() <= 1);
-
-  evp_pkey_set0(this, nullptr, nullptr);
-}
+EvpPkey::~EvpPkey() { evp_pkey_set0(this, nullptr, nullptr); }
 
 void EVP_PKEY_free(EVP_PKEY *pkey) {
   if (pkey == nullptr) {
@@ -60,16 +49,12 @@
   }
 
   auto *impl = FromOpaque(pkey);
-  if (!CRYPTO_refcount_dec_and_test_zero(&impl->references)) {
-    return;
-  }
-
-  Delete(impl);
+  impl->DecRefInternal();
 }
 
 int EVP_PKEY_up_ref(EVP_PKEY *pkey) {
   auto *impl = FromOpaque(pkey);
-  CRYPTO_refcount_inc(&impl->references);
+  impl->UpRefInternal();
   return 1;
 }
 
diff --git a/crypto/evp/internal.h b/crypto/evp/internal.h
index 9fa80ad..c948e4d 100644
--- a/crypto/evp/internal.h
+++ b/crypto/evp/internal.h
@@ -134,24 +134,21 @@
   void (*pkey_free)(EvpPkey *pkey);
 } /* EVP_PKEY_ASN1_METHOD */;
 
-class EvpPkey : public evp_pkey_st {
+class EvpPkey : public evp_pkey_st, public RefCounted<EvpPkey> {
  public:
-  ~EvpPkey();
-
-  bssl::CRYPTO_refcount_t references;
+  EvpPkey();
 
   // pkey contains a pointer to a structure dependent on |ameth|.
-  void *pkey;
+  void *pkey = nullptr;
 
   // ameth contains a pointer to a method table that determines the key type, or
   // nullptr if the key is empty.
-  const bssl::EVP_PKEY_ASN1_METHOD *ameth;
-} /* EVP_PKEY */;
+  const bssl::EVP_PKEY_ASN1_METHOD *ameth = nullptr;
 
-// |UniquePtr|s to EvpPkey are actually intrusive |shared_ptr|s!
-// TODO(crbug.com/481633975): find a better way for handling this.
-BORINGSSL_MAKE_DELETER(EvpPkey, EVP_PKEY_free)
-BORINGSSL_MAKE_UP_REF(EvpPkey, EVP_PKEY_up_ref)
+ private:
+  ~EvpPkey();
+  friend RefCounted;
+} /* EVP_PKEY */;
 
 #define EVP_PKEY_OP_UNDEFINED 0
 #define EVP_PKEY_OP_KEYGEN (1 << 2)