Add EC_POINT_point2cbb.

This slightly simplifies the SSL_ECDH code and will be useful later on
in reimplementing the key parsing logic.

Change-Id: Ie41ea5fd3a9a734b3879b715fbf57bd991e23799
Reviewed-on: https://boringssl-review.googlesource.com/6858
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/ec/oct.c b/crypto/ec/oct.c
index e39337d..9e18535 100644
--- a/crypto/ec/oct.c
+++ b/crypto/ec/oct.c
@@ -68,6 +68,7 @@
 #include <openssl/ec.h>
 
 #include <openssl/bn.h>
+#include <openssl/bytestring.h>
 #include <openssl/err.h>
 
 #include "internal.h"
@@ -268,6 +269,17 @@
   return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
 }
 
+int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point,
+                       point_conversion_form_t form, BN_CTX *ctx) {
+  size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
+  if (len == 0) {
+    return 0;
+  }
+  uint8_t *p;
+  return CBB_add_space(out, &p, len) &&
+         EC_POINT_point2oct(group, point, form, p, len, ctx) == len;
+}
+
 int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
                                              EC_POINT *point, const BIGNUM *x_,
                                              int y_bit, BN_CTX *ctx) {
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 82f84ea..230d395 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -239,6 +239,13 @@
                                          point_conversion_form_t form,
                                          uint8_t *buf, size_t len, BN_CTX *ctx);
 
+/* EC_POINT_point2cbb behaves like |EC_POINT_point2oct| but appends the
+ * serialised point to |cbb|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group,
+                                      const EC_POINT *point,
+                                      point_conversion_form_t form,
+                                      BN_CTX *ctx);
+
 /* EC_POINT_oct2point sets |point| from |len| bytes of X9.62 format
  * serialisation in |buf|. It returns one on success and zero otherwise. The
  * |ctx| argument may be used if not NULL. */
diff --git a/ssl/ssl_ecdh.c b/ssl/ssl_ecdh.c
index cad8ebc..700d947 100644
--- a/ssl/ssl_ecdh.c
+++ b/ssl/ssl_ecdh.c
@@ -65,21 +65,12 @@
     }
   } while (BN_is_zero(private_key));
 
-  /* Compute the corresponding public key. */
+  /* Compute the corresponding public key and serialize it. */
   public_key = EC_POINT_new(group);
   if (public_key == NULL ||
-      !EC_POINT_mul(group, public_key, private_key, NULL, NULL, bn_ctx)) {
-    goto err;
-  }
-
-  /* Serialize the public key. */
-  size_t len = EC_POINT_point2oct(
-      group, public_key, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx);
-  uint8_t *ptr;
-  if (len == 0 ||
-      !CBB_add_space(out, &ptr, len) ||
-      EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED, ptr,
-                         len, bn_ctx) != len) {
+      !EC_POINT_mul(group, public_key, private_key, NULL, NULL, bn_ctx) ||
+      !EC_POINT_point2cbb(out, group, public_key, POINT_CONVERSION_UNCOMPRESSED,
+                          bn_ctx)) {
     goto err;
   }