Convert SSL_ECDH_CTX to C++.

SSLECDHContext has the acronyms problem, so I went with SSLKeyShare to
match the TLS 1.3 terminology. It's also a little shorter. Accept and
Finish, for now, take raw output pointers in anticipation of some
bssl::Array and maybe bssl::CleansedArray types.

Bug: 132
Change-Id: I427c7c0eac95704f3ad093676c504c2848f5acb9
Reviewed-on: https://boringssl-review.googlesource.com/18265
Reviewed-by: Steven Valdez <svaldez@google.com>
diff --git a/ssl/internal.h b/ssl/internal.h
index f7d1cde..fb02d35 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -747,48 +747,50 @@
 int custom_ext_add_serverhello(SSL_HANDSHAKE *hs, CBB *extensions);
 
 
-/* ECDH groups. */
+/* Key shares. */
 
-struct SSL_ECDH_CTX;
+/* SSLKeyShare abstracts over Diffie-Hellman-like key exchanges. */
+class SSLKeyShare {
+ public:
+  virtual ~SSLKeyShare() {}
 
-/* An SSL_ECDH_METHOD is an implementation of ECDH-like key exchanges for
- * TLS. */
-struct SSL_ECDH_METHOD {
-  int nid;
-  uint16_t group_id;
-  const char name[8];
+  /* Create returns a SSLKeyShare instance for use with group |group_id| or
+   * nullptr on error. */
+  static UniquePtr<SSLKeyShare> Create(uint16_t group_id);
 
-  /* cleanup releases state in |ctx|. */
-  void (*cleanup)(SSL_ECDH_CTX *ctx);
+  /* GroupID returns the group ID. */
+  virtual uint16_t GroupID() const = 0;
 
-  /* offer generates a keypair and writes the public value to
-   * |out_public_key|. It returns one on success and zero on error. */
-  int (*offer)(SSL_ECDH_CTX *ctx, CBB *out_public_key);
+  /* Offer generates a keypair and writes the public value to
+   * |out_public_key|. It returns true on success and false on error. */
+  virtual bool Offer(CBB *out_public_key) = 0;
 
-  /* accept performs a key exchange against the |peer_key| generated by |offer|.
-   * On success, it returns one, writes the public value to |out_public_key|,
+  /* Accept performs a key exchange against the |peer_key| generated by |offer|.
+   * On success, it returns true, writes the public value to |out_public_key|,
    * and sets |*out_secret| and |*out_secret_len| to a newly-allocated buffer
    * containing the shared secret. The caller must release this buffer with
-   * |OPENSSL_free|. On failure, it returns zero and sets |*out_alert| to an
-   * alert to send to the peer. */
-  int (*accept)(SSL_ECDH_CTX *ctx, CBB *out_public_key, uint8_t **out_secret,
-                size_t *out_secret_len, uint8_t *out_alert,
-                const uint8_t *peer_key, size_t peer_key_len);
+   * |OPENSSL_free|. On failure, it returns false and sets |*out_alert| to an
+   * alert to send to the peer.
+   *
+   * The default implementation calls |Offer| and then |Finish|, assuming a key
+   * exchange protocol where the peers are symmetric.
+   *
+   * TODO(davidben): out_secret should be a smart pointer. */
+  virtual bool Accept(CBB *out_public_key, uint8_t **out_secret,
+                      size_t *out_secret_len, uint8_t *out_alert,
+                      const uint8_t *peer_key, size_t peer_key_len);
 
-  /* finish performs a key exchange against the |peer_key| generated by
-   * |accept|. On success, it returns one and sets |*out_secret| and
+  /* Finish performs a key exchange against the |peer_key| generated by
+   * |Accept|. On success, it returns true and sets |*out_secret| and
    * |*out_secret_len| to a newly-allocated buffer containing the shared
    * secret. The caller must release this buffer with |OPENSSL_free|. On
    * failure, it returns zero and sets |*out_alert| to an alert to send to the
-   * peer. */
-  int (*finish)(SSL_ECDH_CTX *ctx, uint8_t **out_secret, size_t *out_secret_len,
-                uint8_t *out_alert, const uint8_t *peer_key,
-                size_t peer_key_len);
-};
-
-struct SSL_ECDH_CTX {
-  const SSL_ECDH_METHOD *method;
-  void *data;
+   * peer.
+   *
+   * TODO(davidben): out_secret should be a smart pointer. */
+  virtual bool Finish(uint8_t **out_secret, size_t *out_secret_len,
+                      uint8_t *out_alert, const uint8_t *peer_key,
+                      size_t peer_key_len) = 0;
 };
 
 /* ssl_nid_to_group_id looks up the group corresponding to |nid|. On success, it
@@ -801,36 +803,6 @@
  * returns one. Otherwise, it returns zero. */
 int ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len);
 
-/* SSL_ECDH_CTX_init sets up |ctx| for use with curve |group_id|. It returns one
- * on success and zero on error. */
-int SSL_ECDH_CTX_init(SSL_ECDH_CTX *ctx, uint16_t group_id);
-
-/* SSL_ECDH_CTX_cleanup releases memory associated with |ctx|. It is legal to
- * call it in the zero state. */
-void SSL_ECDH_CTX_cleanup(SSL_ECDH_CTX *ctx);
-
-/* SSL_ECDH_CTX_get_id returns the group ID for |ctx|. */
-uint16_t SSL_ECDH_CTX_get_id(const SSL_ECDH_CTX *ctx);
-
-/* SSL_ECDH_CTX_get_key calls the |get_key| method of |SSL_ECDH_METHOD|. */
-int SSL_ECDH_CTX_get_key(SSL_ECDH_CTX *ctx, CBS *cbs, CBS *out);
-
-/* SSL_ECDH_CTX_add_key calls the |add_key| method of |SSL_ECDH_METHOD|. */
-int SSL_ECDH_CTX_add_key(SSL_ECDH_CTX *ctx, CBB *cbb, CBB *out_contents);
-
-/* SSL_ECDH_CTX_offer calls the |offer| method of |SSL_ECDH_METHOD|. */
-int SSL_ECDH_CTX_offer(SSL_ECDH_CTX *ctx, CBB *out_public_key);
-
-/* SSL_ECDH_CTX_accept calls the |accept| method of |SSL_ECDH_METHOD|. */
-int SSL_ECDH_CTX_accept(SSL_ECDH_CTX *ctx, CBB *out_public_key,
-                        uint8_t **out_secret, size_t *out_secret_len,
-                        uint8_t *out_alert, const uint8_t *peer_key,
-                        size_t peer_key_len);
-
-/* SSL_ECDH_CTX_finish the |finish| method of |SSL_ECDH_METHOD|. */
-int SSL_ECDH_CTX_finish(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
-                        size_t *out_secret_len, uint8_t *out_alert,
-                        const uint8_t *peer_key, size_t peer_key_len);
 
 /* Handshake messages. */
 
@@ -1148,8 +1120,8 @@
    * TLS 1.3. */
   uint16_t retry_group = 0;
 
-  /* ecdh_ctx is the current ECDH instance. */
-  SSL_ECDH_CTX ecdh_ctx;
+  /* key_share is the current key exchange instance. */
+  UniquePtr<SSLKeyShare> key_share;
 
   /* transcript is the current handshake transcript. */
   SSLTranscript transcript;