Commit 8313a787 authored by Benjamin Kaduk's avatar Benjamin Kaduk Committed by Rich Salz
Browse files

Allow an ALPN callback to pretend to not exist



RFC 7301 mandates that the server SHALL respond with a fatal
"no_application_protocol" alert when there is no overlap between
the client's supplied list and the server's list of supported protocols.
In commit 06217867 we changed from
ignoring non-success returns from the supplied alpn_select_cb() to
treating such non-success returns as indicative of non-overlap and
sending the fatal alert.

In effect, this is using the presence of an alpn_select_cb() as a proxy
to attempt to determine whether the application has configured a list
of supported protocols.  However, there may be cases in which an
application's architecture leads it to supply an alpn_select_cb() but
have that callback be configured to take no action on connections that
do not have ALPN configured; returning SSL_TLSEXT_ERR_NOACK from
the callback would be the natural way to do so.  Unfortunately, the
aforementioned behavior change also treated SSL_TLSEXT_ERR_NOACK as
indicative of no overlap and terminated the connection; this change
supplies special handling for SSL_TLSEXT_ERR_NOACK returns from the
callback.  In effect, it provides a way for a callback to obtain the
behavior that would have occurred if no callback was registered at
all, which was not possible prior to this change.

Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2570)
parent f120fa1e
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -113,9 +113,15 @@ The ALPN select callback B<cb>, must return one of the following:

ALPN protocol selected.

=item SSL_TLSEXT_ERR_ALERT_FATAL

There was no overlap between the client's supplied list and the server
configuration.

=item SSL_TLSEXT_ERR_NOACK

ALPN protocol not selected.
ALPN protocol not selected, e.g., because no ALPN protocols are configured for
this connection.

=back

+3 −0
Original line number Diff line number Diff line
@@ -919,6 +919,9 @@ static int final_alpn(SSL *s, unsigned int context, int sent, int *al)
            /* ALPN takes precedence over NPN. */
            s->s3->npn_seen = 0;
#endif
        } else if (r == SSL_TLSEXT_ERR_NOACK) {
            /* Behave as if no callback was present. */
            return 1;
        } else {
            *al = SSL_AD_NO_APPLICATION_PROTOCOL;
            return 0;
+1 −1
Original line number Diff line number Diff line
@@ -413,7 +413,7 @@ static int server_alpn_cb(SSL *s, const unsigned char **out,
    *out = tmp_out;
    /* Unlike NPN, we don't tolerate a mismatch. */
    return ret == OPENSSL_NPN_NEGOTIATED ? SSL_TLSEXT_ERR_OK
        : SSL_TLSEXT_ERR_NOACK;
        : SSL_TLSEXT_ERR_ALERT_FATAL;
}

#ifndef OPENSSL_NO_SRP