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;