Forbid a server from negotiating both ALPN and NPN.

If the two extensions select different next protocols (quite possible since one
is server-selected and the other is client-selected), things will break. This
matches the behavior of NSS (Firefox) and Go.

Change-Id: Ie1da97bf062b91a370c85c12bc61423220a22f36
Reviewed-on: https://boringssl-review.googlesource.com/5780
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 2eeffab..40b9752 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1410,6 +1410,13 @@
   assert(!SSL_IS_DTLS(ssl));
   assert(ssl->ctx->next_proto_select_cb != NULL);
 
+  if (ssl->s3->alpn_selected != NULL) {
+    /* NPN and ALPN may not be negotiated in the same connection. */
+    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+    OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
+    return 0;
+  }
+
   const uint8_t *const orig_contents = CBS_data(contents);
   const size_t orig_len = CBS_len(contents);
 
@@ -1585,6 +1592,13 @@
   assert(!ssl->s3->initial_handshake_complete);
   assert(ssl->alpn_client_proto_list != NULL);
 
+  if (ssl->s3->next_proto_neg_seen) {
+    /* NPN and ALPN may not be negotiated in the same connection. */
+    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+    OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
+    return 0;
+  }
+
   /* The extension data consists of a ProtocolNameList which must have
    * exactly one ProtocolName. Each of these is length-prefixed. */
   CBS protocol_name_list, protocol_name;