Implement custom extensions.

This change mirrors upstream's custom extension API because we have some
internal users that depend on it.

Change-Id: I408e442de0a55df7b05c872c953ff048cd406513
Reviewed-on: https://boringssl-review.googlesource.com/5471
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/base.h b/include/openssl/base.h
index 84400ae..4618ed2 100644
--- a/include/openssl/base.h
+++ b/include/openssl/base.h
@@ -214,6 +214,7 @@
 typedef struct sha512_state_st SHA512_CTX;
 typedef struct sha_state_st SHA_CTX;
 typedef struct ssl_ctx_st SSL_CTX;
+typedef struct ssl_custom_extension SSL_CUSTOM_EXTENSION;
 typedef struct ssl_st SSL;
 typedef struct st_ERR_FNS ERR_FNS;
 typedef struct v3_ext_ctx X509V3_CTX;
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 656a901..02445bf 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -768,6 +768,92 @@
                                       size_t *out_len, size_t max_out);
 
 
+/* Custom extensions.
+ *
+ * The custom extension functions allow TLS extensions to be added to
+ * ClientHello and ServerHello messages. */
+
+/* SSL_custom_ext_add_cb is a callback function that is called when the
+ * ClientHello (for clients) or ServerHello (for servers) is constructed. In
+ * the case of a server, this callback will only be called for a given
+ * extension if the ClientHello contained that extension – it's not possible to
+ * inject extensions into a ServerHello that the client didn't request.
+ *
+ * When called, |extension_value| will contain the extension number that is
+ * being considered for addition (so that a single callback can handle multiple
+ * extensions). If the callback wishes to include the extension, it must set
+ * |*out| to point to |*out_len| bytes of extension contents and return one. In
+ * this case, the corresponding |SSL_custom_ext_free_cb| callback will later be
+ * called with the value of |*out| once that data has been copied.
+ *
+ * If the callback does not wish to add an extension it must return zero.
+ *
+ * Alternatively, the callback can abort the connection by setting
+ * |*out_alert_value| to a TLS alert number and returning -1. */
+typedef int (*SSL_custom_ext_add_cb)(SSL *ssl, unsigned extension_value,
+                                     const uint8_t **out, size_t *out_len,
+                                     int *out_alert_value, void *add_arg);
+
+/* SSL_custom_ext_free_cb is a callback function that is called by OpenSSL iff
+ * an |SSL_custom_ext_add_cb| callback previously returned one. In that case,
+ * this callback is called and passed the |out| pointer that was returned by
+ * the add callback. This is to free any dynamically allocated data created by
+ * the add callback. */
+typedef void (*SSL_custom_ext_free_cb)(SSL *ssl, unsigned extension_value,
+                                       const uint8_t *out, void *add_arg);
+
+/* SSL_custom_ext_parse_cb is a callback function that is called by OpenSSL to
+ * parse an extension from the peer: that is from the ServerHello for a client
+ * and from the ClientHello for a server.
+ *
+ * When called, |extension_value| will contain the extension number and the
+ * contents of the extension are |contents_len| bytes at |contents|.
+ *
+ * The callback must return one to continue the handshake. Otherwise, if it
+ * returns zero, a fatal alert with value |*out_alert_value| is sent and the
+ * handshake is aborted. */
+typedef int (*SSL_custom_ext_parse_cb)(SSL *ssl, unsigned extension_value,
+                                       const uint8_t *contents,
+                                       size_t contents_len,
+                                       int *out_alert_value, void *parse_arg);
+
+/* SSL_extension_supported returns one iff OpenSSL internally handles
+ * extensions of type |extension_value|. This can be used to avoid registering
+ * custom extension handlers for extensions that a future version of OpenSSL
+ * may handle internally. */
+OPENSSL_EXPORT int SSL_extension_supported(unsigned extension_value);
+
+/* SSL_CTX_add_client_custom_ext registers callback functions for handling
+ * custom TLS extensions for client connections.
+ *
+ * If |add_cb| is NULL then an empty extension will be added in each
+ * ClientHello. Otherwise, see the comment for |SSL_custom_ext_add_cb| about
+ * this callback.
+ *
+ * The |free_cb| may be NULL if |add_cb| doesn't dynamically allocate data that
+ * needs to be freed.
+ *
+ * It returns one on success or zero on error. It's always an error to register
+ * callbacks for the same extension twice, or to register callbacks for an
+ * extension that OpenSSL handles internally. See |SSL_extension_supported| to
+ * discover, at runtime, which extensions OpenSSL handles internally. */
+OPENSSL_EXPORT int SSL_CTX_add_client_custom_ext(
+    SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb,
+    SSL_custom_ext_free_cb free_cb, void *add_arg,
+    SSL_custom_ext_parse_cb parse_cb, void *parse_arg);
+
+/* SSL_CTX_add_server_custom_ext is the same as
+ * |SSL_CTX_add_client_custom_ext|, but for server connections.
+ *
+ * Unlike on the client side, if |add_cb| is NULL no extension will be added.
+ * The |add_cb|, if any, will only be called if the ClientHello contained a
+ * matching extension. */
+OPENSSL_EXPORT int SSL_CTX_add_server_custom_ext(
+    SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb,
+    SSL_custom_ext_free_cb free_cb, void *add_arg,
+    SSL_custom_ext_parse_cb parse_cb, void *parse_arg);
+
+
 /* Session tickets. */
 
 /* SSL_CTX_get_tlsext_ticket_keys writes |ctx|'s session ticket key material to
@@ -1221,6 +1307,10 @@
 
   CRYPTO_EX_DATA ex_data;
 
+  /* custom_*_extensions stores any callback sets for custom extensions. Note
+   * that these pointers will be NULL if the stack would otherwise be empty. */
+  STACK_OF(SSL_CUSTOM_EXTENSION) *client_custom_extensions;
+  STACK_OF(SSL_CUSTOM_EXTENSION) *server_custom_extensions;
 
   /* Default values used when no per-SSL value is defined follow */
 
@@ -2945,6 +3035,8 @@
 #define SSL_R_ERROR_ADDING_EXTENSION 281
 #define SSL_R_ERROR_PARSING_EXTENSION 282
 #define SSL_R_MISSING_EXTENSION 283
+#define SSL_R_CUSTOM_EXTENSION_CONTENTS_TOO_LARGE 284
+#define SSL_R_CUSTOM_EXTENSION_ERROR 285
 #define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
 #define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
 #define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index 541b039..faf69ab 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -453,6 +453,16 @@
       uint32_t received;
     } extensions;
 
+    union {
+      /* sent is a bitset where the bits correspond to elements of
+       * |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that
+       * extension was sent in a ClientHello. It's not used by servers. */
+      uint16_t sent;
+      /* received is a bitset, like |sent|, but is used by servers to record
+       * which custom extensions were received from a client. The bits here
+       * correspond to |server_custom_extensions|. */
+      uint16_t received;
+    } custom_extensions;
 
     /* SNI extension */
 
diff --git a/include/openssl/stack.h b/include/openssl/stack.h
index 5f9b683..36a0397 100644
--- a/include/openssl/stack.h
+++ b/include/openssl/stack.h
@@ -147,6 +147,7 @@
  * STACK_OF:POLICY_MAPPING
  * STACK_OF:RSA_additional_prime
  * STACK_OF:SSL_COMP
+ * STACK_OF:SSL_CUSTOM_EXTENSION
  * STACK_OF:STACK_OF_X509_NAME_ENTRY
  * STACK_OF:SXNETID
  * STACK_OF:X509
diff --git a/include/openssl/stack_macros.h b/include/openssl/stack_macros.h
index a4dc926..08097af 100644
--- a/include/openssl/stack_macros.h
+++ b/include/openssl/stack_macros.h
@@ -2106,6 +2106,99 @@
       CHECKED_CAST(void *(*)(void *), SSL_COMP *(*)(SSL_COMP *), copy_func), \
       CHECKED_CAST(void (*)(void *), void (*)(SSL_COMP *), free_func)))
 
+/* SSL_CUSTOM_EXTENSION */
+#define sk_SSL_CUSTOM_EXTENSION_new(comp)                                      \
+  ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_new(CHECKED_CAST(                      \
+      stack_cmp_func,                                                          \
+      int (*)(const SSL_CUSTOM_EXTENSION **a, const SSL_CUSTOM_EXTENSION **b), \
+      comp)))
+
+#define sk_SSL_CUSTOM_EXTENSION_new_null() \
+  ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_new_null())
+
+#define sk_SSL_CUSTOM_EXTENSION_num(sk) \
+  sk_num(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_zero(sk) \
+  sk_zero(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk));
+
+#define sk_SSL_CUSTOM_EXTENSION_value(sk, i)                              \
+  ((SSL_CUSTOM_EXTENSION *)sk_value(                                      \
+      CHECKED_CAST(_STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+      (i)))
+
+#define sk_SSL_CUSTOM_EXTENSION_set(sk, i, p)                            \
+  ((SSL_CUSTOM_EXTENSION *)sk_set(                                       \
+      CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), (i), \
+      CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p)))
+
+#define sk_SSL_CUSTOM_EXTENSION_free(sk) \
+  sk_free(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_pop_free(sk, free_func)                        \
+  sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk),    \
+              CHECKED_CAST(void (*)(void *), void (*)(SSL_CUSTOM_EXTENSION *), \
+                           free_func))
+
+#define sk_SSL_CUSTOM_EXTENSION_insert(sk, p, where)                      \
+  sk_insert(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+            CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p), (where))
+
+#define sk_SSL_CUSTOM_EXTENSION_delete(sk, where) \
+  ((SSL_CUSTOM_EXTENSION *)sk_delete(             \
+      CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), (where)))
+
+#define sk_SSL_CUSTOM_EXTENSION_delete_ptr(sk, p)                   \
+  ((SSL_CUSTOM_EXTENSION *)sk_delete_ptr(                           \
+      CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+      CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p)))
+
+#define sk_SSL_CUSTOM_EXTENSION_find(sk, out_index, p)                  \
+  sk_find(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+          (out_index), CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p))
+
+#define sk_SSL_CUSTOM_EXTENSION_shift(sk) \
+  ((SSL_CUSTOM_EXTENSION *)sk_shift(      \
+      CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk)))
+
+#define sk_SSL_CUSTOM_EXTENSION_push(sk, p)                             \
+  sk_push(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+          CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p))
+
+#define sk_SSL_CUSTOM_EXTENSION_pop(sk) \
+  ((SSL_CUSTOM_EXTENSION *)sk_pop(      \
+      CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk)))
+
+#define sk_SSL_CUSTOM_EXTENSION_dup(sk)      \
+  ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_dup( \
+      CHECKED_CAST(_STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, sk)))
+
+#define sk_SSL_CUSTOM_EXTENSION_sort(sk) \
+  sk_sort(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_is_sorted(sk) \
+  sk_is_sorted(                               \
+      CHECKED_CAST(_STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_set_cmp_func(sk, comp)                       \
+  ((int (*)(const SSL_CUSTOM_EXTENSION **a, const SSL_CUSTOM_EXTENSION **b)) \
+       sk_set_cmp_func(                                                      \
+           CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk),     \
+           CHECKED_CAST(stack_cmp_func,                                      \
+                        int (*)(const SSL_CUSTOM_EXTENSION **a,              \
+                                const SSL_CUSTOM_EXTENSION **b),             \
+                        comp)))
+
+#define sk_SSL_CUSTOM_EXTENSION_deep_copy(sk, copy_func, free_func)        \
+  ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_deep_copy(                         \
+      CHECKED_CAST(const _STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, \
+                   sk),                                                    \
+      CHECKED_CAST(void *(*)(void *),                                      \
+                   SSL_CUSTOM_EXTENSION *(*)(SSL_CUSTOM_EXTENSION *),      \
+                   copy_func),                                             \
+      CHECKED_CAST(void (*)(void *), void (*)(SSL_CUSTOM_EXTENSION *),     \
+                   free_func)))
+
 /* STACK_OF_X509_NAME_ENTRY */
 #define sk_STACK_OF_X509_NAME_ENTRY_new(comp)                      \
   ((STACK_OF(STACK_OF_X509_NAME_ENTRY) *)sk_new(CHECKED_CAST(      \