Fix OBJ_dup's handling of malloc failures

r->data doesn't get freed in the error path. Since we have a functional
ASN1_OBJECT, just use ASN1_OBJECT_free to clean up the temporary.

Change-Id: Ie0583048e8c781bd02807895a89ed8627dfc7478
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/95987
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Lily Chen <chlily@google.com>
Presubmit-BoringSSL-Verified: boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Lily Chen <chlily@google.com>
diff --git a/crypto/asn1/a_object.cc b/crypto/asn1/a_object.cc
index 125058a..1ed5ee1 100644
--- a/crypto/asn1/a_object.cc
+++ b/crypto/asn1/a_object.cc
@@ -158,12 +158,12 @@
     return;
   }
   if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
-    OPENSSL_free((void *)a->sn);
-    OPENSSL_free((void *)a->ln);
+    OPENSSL_free(const_cast<char *>(a->sn));
+    OPENSSL_free(const_cast<char *>(a->ln));
     a->sn = a->ln = nullptr;
   }
   if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
-    OPENSSL_free((void *)a->data);
+    OPENSSL_free(const_cast<uint8_t *>(a->data));
     a->data = nullptr;
     a->length = 0;
   }
diff --git a/crypto/obj/obj.cc b/crypto/obj/obj.cc
index a6e6e5a..04cc4f8 100644
--- a/crypto/obj/obj.cc
+++ b/crypto/obj/obj.cc
@@ -57,63 +57,48 @@
 }
 
 ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) {
-  ASN1_OBJECT *r;
-  unsigned char *data = nullptr;
-  char *sn = nullptr, *ln = nullptr;
-
   if (o == nullptr) {
     return nullptr;
   }
 
   if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
     // TODO(fork): this is a little dangerous.
-    return (ASN1_OBJECT *)o;
+    return const_cast<ASN1_OBJECT *>(o);
   }
 
-  r = ASN1_OBJECT_new();
+  UniquePtr<ASN1_OBJECT> r(ASN1_OBJECT_new());
   if (r == nullptr) {
     OPENSSL_PUT_ERROR(OBJ, ERR_R_ASN1_LIB);
     return nullptr;
   }
-  r->ln = r->sn = nullptr;
 
-  // once data is attached to an object, it remains const
+  // All fields of the object will be allocated.
+  r->flags = o->flags | ASN1_OBJECT_FLAG_DYNAMIC |
+             ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+
   r->data = reinterpret_cast<uint8_t *>(OPENSSL_memdup(o->data, o->length));
   if (o->length != 0 && r->data == nullptr) {
-    goto err;
+    return nullptr;
   }
 
   r->length = o->length;
   r->nid = o->nid;
 
   if (o->ln != nullptr) {
-    ln = OPENSSL_strdup(o->ln);
-    if (ln == nullptr) {
-      goto err;
+    r->ln = OPENSSL_strdup(o->ln);
+    if (r->ln == nullptr) {
+      return nullptr;
     }
   }
 
   if (o->sn != nullptr) {
-    sn = OPENSSL_strdup(o->sn);
-    if (sn == nullptr) {
-      goto err;
+    r->sn = OPENSSL_strdup(o->sn);
+    if (r->sn == nullptr) {
+      return nullptr;
     }
   }
 
-  r->sn = sn;
-  r->ln = ln;
-
-  r->flags =
-      o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
-                  ASN1_OBJECT_FLAG_DYNAMIC_DATA);
-  return r;
-
-err:
-  OPENSSL_free(ln);
-  OPENSSL_free(sn);
-  OPENSSL_free(data);
-  OPENSSL_free(r);
-  return nullptr;
+  return r.release();
 }
 
 int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {