Move ALPN processing into an extension finalisation function
authorMatt Caswell <matt@openssl.org>
Sat, 26 Nov 2016 11:22:50 +0000 (11:22 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 8 Dec 2016 17:18:46 +0000 (17:18 +0000)
Perl changes reviewed by Richard Levitte. Non-perl changes reviewed by Rich
Salz

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
ssl/statem/extensions.c
ssl/statem/extensions_srvr.c

index c6c9813..4c8ad7f 100644 (file)
@@ -21,6 +21,7 @@ static int tls_ext_init_status_request(SSL *s, unsigned int context);
 static int tls_ext_init_npn(SSL *s, unsigned int context);
 #endif
 static int tls_ext_init_alpn(SSL *s, unsigned int context);
+static int tls_ext_final_alpn(SSL *s, unsigned int context, int sent, int *al);
 static int tls_ext_init_sig_algs(SSL *s, unsigned int context);
 #ifndef OPENSSL_NO_SRP
 static int tls_ext_init_srp(SSL *s, unsigned int context);
@@ -163,13 +164,17 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     },
 #endif
     {
+        /*
+         * Must appear in this list after server_name so that finalisation
+         * happens after server_name callbacks
+         */
         TLSEXT_TYPE_application_layer_protocol_negotiation,
         tls_ext_init_alpn,
         tls_parse_client_alpn,
         tls_parse_server_alpn,
         tls_construct_server_alpn,
         tls_construct_client_alpn,
-        NULL,
+        tls_ext_final_alpn,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
         | EXT_TLS1_3_ENCRYPTED_EXTENSIONS
     },
@@ -787,6 +792,48 @@ static int tls_ext_init_alpn(SSL *s, unsigned int context)
     return 1;
 }
 
+
+
+/*
+ * Process the ALPN extension in a ClientHello.
+ * al: a pointer to the alert value to send in the event of a failure.
+ * returns 1 on success, 0 on error.
+ */
+static int tls_ext_final_alpn(SSL *s, unsigned int context, int sent, int *al)
+{
+    const unsigned char *selected = NULL;
+    unsigned char selected_len = 0;
+
+    if (!s->server)
+        return 1;
+
+    if (s->ctx->alpn_select_cb != NULL && s->s3->alpn_proposed != NULL) {
+        int r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
+                                       s->s3->alpn_proposed,
+                                       (unsigned int)s->s3->alpn_proposed_len,
+                                       s->ctx->alpn_select_cb_arg);
+
+        if (r == SSL_TLSEXT_ERR_OK) {
+            OPENSSL_free(s->s3->alpn_selected);
+            s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len);
+            if (s->s3->alpn_selected == NULL) {
+                *al = SSL_AD_INTERNAL_ERROR;
+                return 0;
+            }
+            s->s3->alpn_selected_len = selected_len;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+            /* ALPN takes precedence over NPN. */
+            s->s3->next_proto_neg_seen = 0;
+#endif
+        } else {
+            *al = SSL_AD_NO_APPLICATION_PROTOCOL;
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
 static int tls_ext_init_sig_algs(SSL *s, unsigned int context)
 {
     /* Clear any signature algorithms extension received */
index 5a796ce..50b42c0 100644 (file)
@@ -672,43 +672,6 @@ int tls_scan_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello, int *al)
                                     hello->num_extensions, al);
 }
 
-/*
- * Process the ALPN extension in a ClientHello.
- * al: a pointer to the alert value to send in the event of a failure.
- * returns 1 on success, 0 on error.
- */
-static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
-{
-    const unsigned char *selected = NULL;
-    unsigned char selected_len = 0;
-
-    if (s->ctx->alpn_select_cb != NULL && s->s3->alpn_proposed != NULL) {
-        int r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
-                                       s->s3->alpn_proposed,
-                                       (unsigned int)s->s3->alpn_proposed_len,
-                                       s->ctx->alpn_select_cb_arg);
-
-        if (r == SSL_TLSEXT_ERR_OK) {
-            OPENSSL_free(s->s3->alpn_selected);
-            s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len);
-            if (s->s3->alpn_selected == NULL) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            s->s3->alpn_selected_len = selected_len;
-#ifndef OPENSSL_NO_NEXTPROTONEG
-            /* ALPN takes precedence over NPN. */
-            s->s3->next_proto_neg_seen = 0;
-#endif
-        } else {
-            *al = SSL_AD_NO_APPLICATION_PROTOCOL;
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
 /*
  * Upon success, returns 1.
  * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
@@ -754,10 +717,6 @@ int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
         }
     }
 
-    if (!tls1_alpn_handle_client_hello_late(s, al)) {
-        return 0;
-    }
-
     return 1;
 }