Remove ex_data's dup hook.

The only place it is used is EC_KEY_{dup,copy} and no one calls that
function on an EC_KEY with ex_data. This aligns with functions like
RSAPublicKey_dup which do not copy ex_data. The logic is also somewhat
subtle in the face of malloc errors (upstream's PR 3323).

In fact, we'd even changed the function pointer signature from upstream,
so BoringSSL-only code is needed to pass this pointer in anyway. (I
haven't switched it to CRYPTO_EX_unused because there are some callers
which pass in an implementation anyway.)

Note, in upstream, the dup hook is also used for SSL_SESSIONs when those
are duplicated (for TLS 1.2 ticket renewal or TLS 1.3 resumption). Our
interpretation is that callers should treat those SSL_SESSIONs
equivalently to newly-established ones. This avoids every consumer
providing a dup hook and simplifies the interface.

(I've gone ahead and removed the TODO(fork). I don't think we'll be able
to change this API. Maybe introduce a new one, but it may not be worth
it? Then again, this API is atrocious... I've never seen anyone use argl
and argp even.)

BUG=21

Change-Id: I6c9e9d5a02347cb229d4c084c1e85125bd741d2b
Reviewed-on: https://boringssl-review.googlesource.com/16344
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/dh/dh.c b/crypto/dh/dh.c
index 33c36f3..c884ae3 100644
--- a/crypto/dh/dh.c
+++ b/crypto/dh/dh.c
@@ -465,9 +465,9 @@
 }
 
 int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
-                        CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
+                        CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) {
   int index;
-  if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
+  if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
                                free_func)) {
     return -1;
   }
diff --git a/crypto/dsa/dsa.c b/crypto/dsa/dsa.c
index a0d45bf..58126c3 100644
--- a/crypto/dsa/dsa.c
+++ b/crypto/dsa/dsa.c
@@ -908,9 +908,9 @@
 }
 
 int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
-                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
+                         CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) {
   int index;
-  if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
+  if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
                                free_func)) {
     return -1;
   }
diff --git a/crypto/ex_data.c b/crypto/ex_data.c
index 8555e23..27b9a51 100644
--- a/crypto/ex_data.c
+++ b/crypto/ex_data.c
@@ -127,12 +127,10 @@
   long argl;  /* Arbitary long */
   void *argp; /* Arbitary void pointer */
   CRYPTO_EX_free *free_func;
-  CRYPTO_EX_dup *dup_func;
 };
 
 int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
-                            long argl, void *argp, CRYPTO_EX_dup *dup_func,
-                            CRYPTO_EX_free *free_func) {
+                            long argl, void *argp, CRYPTO_EX_free *free_func) {
   CRYPTO_EX_DATA_FUNCS *funcs;
   int ret = 0;
 
@@ -144,7 +142,6 @@
 
   funcs->argl = argl;
   funcs->argp = argp;
-  funcs->dup_func = dup_func;
   funcs->free_func = free_func;
 
   CRYPTO_STATIC_MUTEX_lock_write(&ex_data_class->lock);
@@ -233,45 +230,6 @@
   ad->sk = NULL;
 }
 
-int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, CRYPTO_EX_DATA *to,
-                       const CRYPTO_EX_DATA *from) {
-  if (from->sk == NULL) {
-    /* In this case, |from| is blank, which is also the initial state of |to|,
-     * so there's nothing to do. */
-    return 1;
-  }
-
-  for (size_t i = 0; i < ex_data_class->num_reserved; i++) {
-    void *ptr = CRYPTO_get_ex_data(from, i);
-    if (!CRYPTO_set_ex_data(to, i, ptr)) {
-      return 0;
-    }
-  }
-
-  STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
-  if (!get_func_pointers(&func_pointers, ex_data_class)) {
-    return 0;
-  }
-
-  for (size_t i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
-    CRYPTO_EX_DATA_FUNCS *func_pointer =
-        sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
-    void *ptr = CRYPTO_get_ex_data(from, i + ex_data_class->num_reserved);
-    if (func_pointer->dup_func) {
-      func_pointer->dup_func(to, from, &ptr, i + ex_data_class->num_reserved,
-                             func_pointer->argl, func_pointer->argp);
-    }
-    if (!CRYPTO_set_ex_data(to, i + ex_data_class->num_reserved, ptr)) {
-      sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers);
-      return 0;
-    }
-  }
-
-  sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers);
-
-  return 1;
-}
-
 void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj,
                          CRYPTO_EX_DATA *ad) {
   if (ad->sk == NULL) {
diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c
index 6663eaf..67b92a7 100644
--- a/crypto/fipsmodule/ec/ec_key.c
+++ b/crypto/fipsmodule/ec/ec_key.c
@@ -201,11 +201,6 @@
       dest->ecdsa_meth = src->ecdsa_meth;
       METHOD_ref(dest->ecdsa_meth);
   }
-  CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), dest, &dest->ex_data);
-  if (!CRYPTO_dup_ex_data(g_ec_ex_data_class_bss_get(), &dest->ex_data,
-                          &src->ex_data)) {
-    return NULL;
-  }
 
   /* copy the rest */
   dest->enc_flag = src->enc_flag;
@@ -502,11 +497,11 @@
 }
 
 int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
-                            CRYPTO_EX_dup *dup_func,
+                            CRYPTO_EX_dup *dup_unused,
                             CRYPTO_EX_free *free_func) {
   int index;
   if (!CRYPTO_get_ex_new_index(g_ec_ex_data_class_bss_get(), &index, argl, argp,
-                               dup_func, free_func)) {
+                               free_func)) {
     return -1;
   }
   return index;
diff --git a/crypto/fipsmodule/rsa/rsa.c b/crypto/fipsmodule/rsa/rsa.c
index ce04bfc..21dcacd 100644
--- a/crypto/fipsmodule/rsa/rsa.c
+++ b/crypto/fipsmodule/rsa/rsa.c
@@ -284,10 +284,10 @@
 }
 
 int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
-                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
+                         CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) {
   int index;
   if (!CRYPTO_get_ex_new_index(g_rsa_ex_data_class_bss_get(), &index, argl,
-                               argp, dup_func, free_func)) {
+                               argp, free_func)) {
     return -1;
   }
   return index;
diff --git a/crypto/internal.h b/crypto/internal.h
index 21a1675..28ec3ee 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -528,7 +528,7 @@
  * zero otherwise. */
 OPENSSL_EXPORT int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class,
                                            int *out_index, long argl,
-                                           void *argp, CRYPTO_EX_dup *dup_func,
+                                           void *argp,
                                            CRYPTO_EX_free *free_func);
 
 /* CRYPTO_set_ex_data sets an extra data pointer on a given object. Each class
@@ -543,13 +543,6 @@
 /* CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA|. */
 OPENSSL_EXPORT void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad);
 
-/* CRYPTO_dup_ex_data duplicates |from| into a freshly allocated
- * |CRYPTO_EX_DATA|, |to|. Both of which are inside objects of the given
- * class. It returns one on success and zero otherwise. */
-OPENSSL_EXPORT int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class,
-                                      CRYPTO_EX_DATA *to,
-                                      const CRYPTO_EX_DATA *from);
-
 /* CRYPTO_free_ex_data frees |ad|, which is embedded inside |obj|, which is an
  * object of the given class. */
 OPENSSL_EXPORT void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class,
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 27b58f4..c2cdd38 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -2101,7 +2101,7 @@
 
 int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
                                     CRYPTO_EX_unused * unused,
-                                    CRYPTO_EX_dup *dup_func,
+                                    CRYPTO_EX_dup *dup_unused,
                                     CRYPTO_EX_free *free_func)
 {
     /*
@@ -2110,7 +2110,7 @@
      */
     int index;
     if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
-                                 dup_func, free_func)) {
+                                 free_func)) {
         return -1;
     }
     return index;
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
index 15118d2..9edfa00 100644
--- a/crypto/x509/x_x509.c
+++ b/crypto/x509/x_x509.c
@@ -188,11 +188,11 @@
 }
 
 int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused * unused,
-                          CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+                          CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func)
 {
     int index;
     if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
-                                 dup_func, free_func)) {
+                                 free_func)) {
         return -1;
     }
     return index;
diff --git a/include/openssl/dh.h b/include/openssl/dh.h
index ed2396d..9f92a06 100644
--- a/include/openssl/dh.h
+++ b/include/openssl/dh.h
@@ -210,7 +210,7 @@
 
 OPENSSL_EXPORT int DH_get_ex_new_index(long argl, void *argp,
                                        CRYPTO_EX_unused *unused,
-                                       CRYPTO_EX_dup *dup_func,
+                                       CRYPTO_EX_dup *dup_unused,
                                        CRYPTO_EX_free *free_func);
 OPENSSL_EXPORT int DH_set_ex_data(DH *d, int idx, void *arg);
 OPENSSL_EXPORT void *DH_get_ex_data(DH *d, int idx);
diff --git a/include/openssl/dsa.h b/include/openssl/dsa.h
index 2988877..afe0291 100644
--- a/include/openssl/dsa.h
+++ b/include/openssl/dsa.h
@@ -296,7 +296,7 @@
 
 OPENSSL_EXPORT int DSA_get_ex_new_index(long argl, void *argp,
                                         CRYPTO_EX_unused *unused,
-                                        CRYPTO_EX_dup *dup_func,
+                                        CRYPTO_EX_dup *dup_unused,
                                         CRYPTO_EX_free *free_func);
 OPENSSL_EXPORT int DSA_set_ex_data(DSA *d, int idx, void *arg);
 OPENSSL_EXPORT void *DSA_get_ex_data(const DSA *d, int idx);
diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h
index 2186f02..3aeaa78 100644
--- a/include/openssl/ec_key.h
+++ b/include/openssl/ec_key.h
@@ -223,7 +223,7 @@
 
 OPENSSL_EXPORT int EC_KEY_get_ex_new_index(long argl, void *argp,
                                            CRYPTO_EX_unused *unused,
-                                           CRYPTO_EX_dup *dup_func,
+                                           CRYPTO_EX_dup *dup_unused,
                                            CRYPTO_EX_free *free_func);
 OPENSSL_EXPORT int EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg);
 OPENSSL_EXPORT void *EC_KEY_get_ex_data(const EC_KEY *r, int idx);
diff --git a/include/openssl/ex_data.h b/include/openssl/ex_data.h
index e78e070..5d1a45c 100644
--- a/include/openssl/ex_data.h
+++ b/include/openssl/ex_data.h
@@ -134,16 +134,14 @@
 
 #if 0 /* Sample */
 
-/* TYPE_get_ex_new_index allocates a new index for |TYPE|. See the
- * descriptions of the callback typedefs for details of when they are
- * called. Any of the callback arguments may be NULL. The |argl| and |argp|
- * arguments are opaque values that are passed to the callbacks. It returns the
- * new index or a negative number on error.
- *
- * TODO(fork): this should follow the standard calling convention. */
+/* TYPE_get_ex_new_index allocates a new index for |TYPE|. An optional
+ * |free_func| argument may be provided which is called when the owning object
+ * is destroyed. See |CRYPTO_EX_free| for details. The |argl| and |argp|
+ * arguments are opaque values that are passed to the callback. It returns the
+ * new index or a negative number on error. */
 OPENSSL_EXPORT int TYPE_get_ex_new_index(long argl, void *argp,
                                          CRYPTO_EX_unused *unused,
-                                         CRYPTO_EX_dup *dup_func,
+                                         CRYPTO_EX_dup *dup_unused,
                                          CRYPTO_EX_free *free_func);
 
 /* TYPE_set_ex_data sets an extra data pointer on |t|. The |index| argument
@@ -176,24 +174,16 @@
 typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
                             int index, long argl, void *argp);
 
-/* CRYPTO_EX_dup is a callback function that is called when an object of the
- * class is being copied and thus the ex_data linked to it also needs to be
- * copied. On entry, |*from_d| points to the data for this index from the
- * original object. When the callback returns, |*from_d| will be set as the
- * data for this index in |to|.
- *
- * This callback may be called with a NULL value for |*from_d| if |from| has no
- * value set for this index. However, the callbacks may also be skipped entirely
- * if no extra data pointers are set on |from| at all. */
-typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
-                          void **from_d, int index, long argl, void *argp);
-
 
 /* Deprecated functions. */
 
 /* CRYPTO_cleanup_all_ex_data does nothing. */
 OPENSSL_EXPORT void CRYPTO_cleanup_all_ex_data(void);
 
+/* CRYPTO_EX_dup is a legacy callback function type which is ignored. */
+typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
+                          void **from_d, int index, long argl, void *argp);
+
 
 /* Private structures. */
 
diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
index c4d7f53..caf4a42 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -454,7 +454,7 @@
 
 OPENSSL_EXPORT int RSA_get_ex_new_index(long argl, void *argp,
                                         CRYPTO_EX_unused *unused,
-                                        CRYPTO_EX_dup *dup_func,
+                                        CRYPTO_EX_dup *dup_unused,
                                         CRYPTO_EX_free *free_func);
 OPENSSL_EXPORT int RSA_set_ex_data(RSA *r, int idx, void *arg);
 OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *r, int idx);
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 581da2a..55e53da 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2913,7 +2913,7 @@
 OPENSSL_EXPORT void *SSL_get_ex_data(const SSL *ssl, int idx);
 OPENSSL_EXPORT int SSL_get_ex_new_index(long argl, void *argp,
                                         CRYPTO_EX_unused *unused,
-                                        CRYPTO_EX_dup *dup_func,
+                                        CRYPTO_EX_dup *dup_unused,
                                         CRYPTO_EX_free *free_func);
 
 OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx,
@@ -2922,14 +2922,14 @@
                                              int idx);
 OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp,
                                                 CRYPTO_EX_unused *unused,
-                                                CRYPTO_EX_dup *dup_func,
+                                                CRYPTO_EX_dup *dup_unused,
                                                 CRYPTO_EX_free *free_func);
 
 OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data);
 OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx);
 OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp,
                                             CRYPTO_EX_unused *unused,
-                                            CRYPTO_EX_dup *dup_func,
+                                            CRYPTO_EX_dup *dup_unused,
                                             CRYPTO_EX_free *free_func);
 
 
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 52e5df0..f416045 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -779,7 +779,7 @@
 OPENSSL_EXPORT int X509_up_ref(X509 *x);
 
 OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
-	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+	     CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func);
 OPENSSL_EXPORT int X509_set_ex_data(X509 *r, int idx, void *arg);
 OPENSSL_EXPORT void *X509_get_ex_data(X509 *r, int idx);
 OPENSSL_EXPORT int		i2d_X509_AUX(X509 *a,unsigned char **pp);
diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h
index 90a9dd6..85aa1f9 100644
--- a/include/openssl/x509_vfy.h
+++ b/include/openssl/x509_vfy.h
@@ -513,7 +513,7 @@
 #endif
 
 OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
-	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+	CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func);
 OPENSSL_EXPORT int	X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data);
 OPENSSL_EXPORT void *	X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
 OPENSSL_EXPORT int	X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index bf2b577..b3e397d 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2048,10 +2048,10 @@
 }
 
 int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
-                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
+                         CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) {
   int index;
   if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl, &index, argl, argp,
-                               dup_func, free_func)) {
+                               free_func)) {
     return -1;
   }
   return index;
@@ -2066,11 +2066,11 @@
 }
 
 int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
-                             CRYPTO_EX_dup *dup_func,
+                             CRYPTO_EX_dup *dup_unused,
                              CRYPTO_EX_free *free_func) {
   int index;
   if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl_ctx, &index, argl, argp,
-                               dup_func, free_func)) {
+                               free_func)) {
     return -1;
   }
   return index;
diff --git a/ssl/ssl_session.c b/ssl/ssl_session.c
index 05ae059..b105cd0 100644
--- a/ssl/ssl_session.c
+++ b/ssl/ssl_session.c
@@ -483,10 +483,10 @@
 
 int SSL_SESSION_get_ex_new_index(long argl, void *argp,
                                  CRYPTO_EX_unused *unused,
-                                 CRYPTO_EX_dup *dup_func,
+                                 CRYPTO_EX_dup *dup_unused,
                                  CRYPTO_EX_free *free_func) {
   int index;
-  if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
+  if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
                                free_func)) {
     return -1;
   }