Document early callback functions.

Also added a SSL_CTX_set_select_certificate_cb setter for
select_certificate_cb so code needn't access SSL_CTX directly. Plus it
serves as a convenient anchor for the documentation.

Change-Id: I23755b910e1d77d4bea7bb9103961181dd3c5efe
Reviewed-on: https://boringssl-review.googlesource.com/6291
Reviewed-by: Adam Langley <alangley@gmail.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 274a20a..1849284 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -425,7 +425,7 @@
  * retry the operation when lookup has completed. Note: when the operation is
  * retried, the early callback will not be called a second time.
  *
- * See also |select_certificate_cb| on |SSL_CTX|. */
+ * See also |SSL_CTX_set_select_certificate_cb|. */
 #define SSL_ERROR_PENDING_CERTIFICATE 12
 
 /* SSL_ERROR_WANT_PRIVATE_KEY_OPERATION indicates the operation failed because
@@ -2540,6 +2540,53 @@
  * unnecessary. */
 OPENSSL_EXPORT uint64_t OPENSSL_get_d5_bug_use_count(void);
 
+/* ssl_early_callback_ctx is passed to certain callbacks that are called very
+ * early on during the server handshake. At this point, much of the SSL* hasn't
+ * been filled out and only the ClientHello can be depended on. */
+struct ssl_early_callback_ctx {
+  SSL *ssl;
+  const uint8_t *client_hello;
+  size_t client_hello_len;
+  const uint8_t *session_id;
+  size_t session_id_len;
+  const uint8_t *cipher_suites;
+  size_t cipher_suites_len;
+  const uint8_t *compression_methods;
+  size_t compression_methods_len;
+  const uint8_t *extensions;
+  size_t extensions_len;
+};
+
+/* SSL_early_callback_ctx_extension_get searches the extensions in |ctx| for an
+ * extension of the given type. If not found, it returns zero. Otherwise it
+ * sets |out_data| to point to the extension contents (not including the type
+ * and length bytes), sets |out_len| to the length of the extension contents
+ * and returns one. */
+OPENSSL_EXPORT int SSL_early_callback_ctx_extension_get(
+    const struct ssl_early_callback_ctx *ctx, uint16_t extension_type,
+    const uint8_t **out_data, size_t *out_len);
+
+/* SSL_CTX_set_select_certificate_cb sets a callback that is called before most
+ * ClientHello processing and before the decision whether to resume a session
+ * is made. The callback may inspect the ClientHello and configure the
+ * connection. It may then return one to continue the handshake or zero to
+ * pause the handshake to perform an asynchronous operation. If paused,
+ * |SSL_get_error| will return |SSL_ERROR_PENDING_CERTIFICATE|.
+ *
+ * Note: The |ssl_early_callback_ctx| is only valid for the duration of the
+ * callback and is not valid while the handshake is paused. Further, unlike with
+ * most callbacks, when the handshake loop is resumed, it will not call the
+ * callback a second time. The caller must finish reconfiguring the connection
+ * before resuming the handshake. */
+OPENSSL_EXPORT void SSL_CTX_set_select_certificate_cb(
+    SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
+
+/* SSL_CTX_set_dos_protection_cb sets a callback that is called once the
+ * resumption decision for a ClientHello has been made. It can return one to
+ * allow the handshake to continue or zero to cause the handshake to abort. */
+OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb(
+    SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
+
 
 /* Underdocumented functions.
  *
@@ -2615,32 +2662,6 @@
 struct ssl_aead_ctx_st;
 typedef struct ssl_aead_ctx_st SSL_AEAD_CTX;
 
-/* ssl_early_callback_ctx is passed to certain callbacks that are called very
- * early on during the server handshake. At this point, much of the SSL* hasn't
- * been filled out and only the ClientHello can be depended on. */
-struct ssl_early_callback_ctx {
-  SSL *ssl;
-  const uint8_t *client_hello;
-  size_t client_hello_len;
-  const uint8_t *session_id;
-  size_t session_id_len;
-  const uint8_t *cipher_suites;
-  size_t cipher_suites_len;
-  const uint8_t *compression_methods;
-  size_t compression_methods_len;
-  const uint8_t *extensions;
-  size_t extensions_len;
-};
-
-/* SSL_early_callback_ctx_extension_get searches the extensions in |ctx| for an
- * extension of the given type. If not found, it returns zero. Otherwise it
- * sets |out_data| to point to the extension contents (not including the type
- * and length bytes), sets |out_len| to the length of the extension contents
- * and returns one. */
-OPENSSL_EXPORT char SSL_early_callback_ctx_extension_get(
-    const struct ssl_early_callback_ctx *ctx, uint16_t extension_type,
-    const uint8_t **out_data, size_t *out_len);
-
 OPENSSL_EXPORT void SSL_CTX_set_info_callback(SSL_CTX *ctx,
                                               void (*cb)(const SSL *ssl,
                                                          int type, int val));
@@ -2797,12 +2818,6 @@
                                                              int type, int val);
 OPENSSL_EXPORT int SSL_state(const SSL *ssl);
 
-/* SSL_CTX_set_dos_protection_cb sets a callback that is called once the
- * resumption decision for a ClientHello has been made. It can return 1 to
- * allow the handshake to continue or zero to cause the handshake to abort. */
-OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb(
-    SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
-
 
 /* Deprecated functions. */
 
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 7b36940..5f729e2 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2651,6 +2651,11 @@
 
 int SSL_is_server(SSL *ssl) { return ssl->server; }
 
+void SSL_CTX_set_select_certificate_cb(
+    SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
+  ctx->select_certificate_cb = cb;
+}
+
 void SSL_CTX_set_dos_protection_cb(
     SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
   ctx->dos_protection_cb = cb;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index c133e51..24ec0a0 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -308,7 +308,7 @@
   return 1;
 }
 
-char SSL_early_callback_ctx_extension_get(
+int SSL_early_callback_ctx_extension_get(
     const struct ssl_early_callback_ctx *ctx, uint16_t extension_type,
     const uint8_t **out_data, size_t *out_len) {
   CBS extensions;
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 8d1f37b..99412d8 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -678,7 +678,7 @@
     SSL_CTX_set_session_cache_mode(ssl_ctx.get(), SSL_SESS_CACHE_BOTH);
   }
 
-  ssl_ctx->select_certificate_cb = SelectCertificateCallback;
+  SSL_CTX_set_select_certificate_cb(ssl_ctx.get(), SelectCertificateCallback);
 
   SSL_CTX_set_next_protos_advertised_cb(
       ssl_ctx.get(), NextProtosAdvertisedCallback, NULL);