Fix some malloc failure crashes.

EVP_MD_CTX_copy_ex was implemented with a memcpy, which doesn't work well when
some of the pointers need to be copied, and ssl_verify_cert_chain didn't
account for set_ex_data failing.

Change-Id: Ieb556aeda6ab2e4c810f27012fefb1e65f860023
Reviewed-on: https://boringssl-review.googlesource.com/5911
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/digest/digest.c b/crypto/digest/digest.c
index ada1166..eb71b07 100644
--- a/crypto/digest/digest.c
+++ b/crypto/digest/digest.c
@@ -129,8 +129,8 @@
   }
 
   EVP_MD_CTX_cleanup(out);
-  memcpy(out, in, sizeof(EVP_MD_CTX));
 
+  out->digest = in->digest;
   if (in->md_data && in->digest->ctx_size) {
     if (tmp_buf) {
       out->md_data = tmp_buf;
@@ -145,6 +145,7 @@
   }
 
   assert(in->pctx == NULL || in->pctx_ops != NULL);
+  out->pctx_ops = in->pctx_ops;
   if (in->pctx && in->pctx_ops) {
     out->pctx = in->pctx_ops->dup(in->pctx);
     if (!out->pctx) {
diff --git a/ssl/internal.h b/ssl/internal.h
index a788b6e..8f477bc 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -994,7 +994,7 @@
 void ssl_cert_set_cert_cb(CERT *cert,
                           int (*cb)(SSL *ssl, void *arg), void *arg);
 
-int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk);
+int ssl_verify_cert_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
 int ssl_add_cert_chain(SSL *s, unsigned long *l);
 void ssl_update_cache(SSL *s, int mode);
 
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 46cb4c0..1506f63 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -293,44 +293,46 @@
   c->cert_cb_arg = arg;
 }
 
-int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) {
-  X509 *x;
-  int i;
-  X509_STORE_CTX ctx;
-
-  if (sk == NULL || sk_X509_num(sk) == 0) {
+int ssl_verify_cert_chain(SSL *ssl, STACK_OF(X509) *cert_chain) {
+  if (cert_chain == NULL || sk_X509_num(cert_chain) == 0) {
     return 0;
   }
 
-  x = sk_X509_value(sk, 0);
-  if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) {
+  X509 *leaf = sk_X509_value(cert_chain, 0);
+  int ret = 0;
+  X509_STORE_CTX ctx;
+  if (!X509_STORE_CTX_init(&ctx, ssl->ctx->cert_store, leaf, cert_chain)) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
     return 0;
   }
-  X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
+  if (!X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(),
+                                  ssl)) {
+    goto err;
+  }
 
   /* We need to inherit the verify parameters. These can be determined by the
    * context: if its a server it will verify SSL client certificates or vice
    * versa. */
-  X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server");
+  X509_STORE_CTX_set_default(&ctx, ssl->server ? "ssl_client" : "ssl_server");
 
   /* Anything non-default in "param" should overwrite anything in the ctx. */
-  X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
+  X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), ssl->param);
 
-  if (s->verify_callback) {
-    X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
+  if (ssl->verify_callback) {
+    X509_STORE_CTX_set_verify_cb(&ctx, ssl->verify_callback);
   }
 
-  if (s->ctx->app_verify_callback != NULL) {
-    i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
+  if (ssl->ctx->app_verify_callback != NULL) {
+    ret = ssl->ctx->app_verify_callback(&ctx, ssl->ctx->app_verify_arg);
   } else {
-    i = X509_verify_cert(&ctx);
+    ret = X509_verify_cert(&ctx);
   }
 
-  s->verify_result = ctx.error;
-  X509_STORE_CTX_cleanup(&ctx);
+  ssl->verify_result = ctx.error;
 
-  return i;
+err:
+  X509_STORE_CTX_cleanup(&ctx);
+  return ret;
 }
 
 static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,