Skip to content

Latest commit

 

History

History
166 lines (116 loc) · 11.3 KB

File metadata and controls

166 lines (116 loc) · 11.3 KB

TLS Application-Layer Protocol Negotiation Extension

In this article, we mainly discuss the Application-Layer Protocol Negotiation extension in the Transport Layer Security (TLS) handshake. For instances that support multiple application protocols on the same TCP or UDP port, this extension allows the application layer to negotiate which protocol will be used in the TLS connection.

I. Introduction

Application-layer protocols are increasingly being encapsulated in the TLS protocol [RFC5246]. This encapsulation allows applications to use port 443, which is already present for secure communication links across nearly the entire global IP infrastructure.

When multiple application protocols are supported on a single server-side port number (for example, port 443), the client and server need to negotiate the application protocol to use for each connection. It is desirable to complete this negotiation without increasing the number of network round trips between the client and server, since each round trip degrades the end-user experience. In addition, it is advantageous to allow certificate selection based on the negotiated application protocol.

This document specifies a TLS extension that allows the application layer to negotiate protocol selection during the TLS handshake. The HTTPbis WG requested this work to address negotiation of HTTP/2 ([HTTP2]) over TLS. However, ALPN is useful for negotiating arbitrary application-layer protocols.

With ALPN, the client sends a list of supported application protocols as part of the TLS ClientHello message. The server selects a protocol and sends the selected protocol as part of the TLS ServerHello message. Thus, application protocol negotiation can be completed during the TLS handshake without adding network round trips, and it allows the server to associate different certificates with each application protocol as needed.

II. Application-Layer Protocol Negotiation

1. The Application-Layer Protocol Negotiation Extension

A new extension type ("application_layer_protocol_negotiation(16)") is defined, which the client may include in its “ClientHello” message.

   enum {
       application_layer_protocol_negotiation(16), (65535)
   } ExtensionType;

The "extension_data" field of the ("application_layer_protocol_negotiation(16)") extension MUST contain a "ProtocolNameList" value.

   opaque ProtocolName<1..2^8-1>;

   struct {
       ProtocolName protocol_name_list<2..2^16-1>
   } ProtocolNameList;

"ProtocolNameList" contains the list of protocols advertised by the client, in descending order of preference. Protocols are named by opaque, non-empty byte strings registered with IANA, as described in Section 6 ("IANA Considerations") of this document. The empty string MUST NOT be included, and byte strings MUST NOT be truncated.

A server that receives a ClientHello containing the "application_layer_protocol_negotiation" extension may return an appropriate protocol selection to the client in response. The server will ignore any protocol names it does not recognize. A new ServerHello extension type ("application_layer_protocol_negotiation(16)") may be returned to the client in the ServerHello message extensions. The structure of the "extension_data" field of the ("application_layer_protocol_negotiation(16)") extension is the same as described above for the client "extension_data", except that "ProtocolNameList" MUST contain exactly one "ProtocolName".

Therefore, a full handshake with the "application_layer_protocol_negotiation" extension in the ClientHello and ServerHello messages has the following flow (compared with Section 7.3 of [RFC5246]):

   Client                                              Server

   ClientHello                     -------->       ServerHello
     (ALPN extension &                               (ALPN extension &
      list of protocols)                              selected protocol)
                                                   Certificate*
                                                   ServerKeyExchange*
                                                   CertificateRequest*
                                   <--------       ServerHelloDone
   Certificate*
   ClientKeyExchange
   CertificateVerify*
   [ChangeCipherSpec]
   Finished                        -------->
                                                   [ChangeCipherSpec]
                                   <--------       Finished
   Application Data                <------->       Application Data

                                 Figure 1

   * Indicates optional or situation-dependent messages that are not always sent.

A short handshake with the "application_layer_protocol_negotiation" extension follows this flow:

   Client                                              Server

   ClientHello                     -------->       ServerHello
     (ALPN extension &                               (ALPN extension &
      list of protocols)                              selected protocol)
                                                   [ChangeCipherSpec]
                                   <--------       Finished
   [ChangeCipherSpec]
   Finished                        -------->
   Application Data                <------->       Application Data

Unlike many other TLS extensions, this extension establishes properties of the connection, not properties of the session. When session resumption or session tickets [RFC5077] are used, the previous contents of this extension are irrelevant, and only the values in the new handshake messages need to be considered.

2. Protocol Selection

The server is expected to have a prioritized list of supported protocols and to select a protocol only if it is supported by the client. In this case, the server should select the highest-priority protocol that it supports and that was also advertised by the client. If the server does not support any of the protocols sent by the client, it should respond with a "no_application_protocol" alert error.

   enum {
       no_application_protocol(120),
       (255)
   } AlertDescription;

Before renegotiation, the protocol identified in the ServerHello "application_layer_protocol_negotiation" extension type is definitive for this connection. The server will not respond with the selected protocol and then subsequently use a different protocol for application data exchange.

III. Design Considerations

The ALPN extension is intended to follow the typical design of TLS protocol extensions. Specifically, in accordance with the established TLS architecture, negotiation is performed entirely within the client/server hello exchange. The ServerHello extension "application_layer_protocol_negotiation" is intended to determine the protocol selected for the connection (until the connection is renegotiated), and is sent in plaintext to allow network elements to provide differentiated service for the connection when the application-layer protocol has not yet been determined and the TCP or UDP port number is therefore ambiguous. By placing ownership of protocol selection with the server, ALPN facilitates the following scenarios: certificate selection or connection rerouting, both of which may be based on the negotiated protocol.

Ultimately, by managing protocol selection in cleartext during the handshake, ALPN avoids introducing errors by attempting to hide the negotiated protocol before the connection has been established. If the protocol needs to be hidden, renegotiation after the connection has been established (which provides genuine TLS security guarantees) is the preferred approach.

IV. Security Considerations

The ALPN extension does not affect the security of TLS session establishment or application data exchange. ALPN is used to provide an externally visible marker for the application-layer protocol associated with a TLS connection. Historically, the application-layer protocol associated with a connection could be determined from the TCP or UDP port number in use.

Implementers and document editors intending to extend the protocol identifier registry by adding new protocol identifiers should take into account that, in TLS version 1.2 and earlier, clients send these identifiers in cleartext. They should also consider that, for at least the next decade, browsers are generally expected to use these earlier versions of TLS in the initial ClientHello.

Extra care must be taken when such identifiers may disclose personally identifiable information, or when such disclosure may enable profiling or expose sensitive information. If any of these concerns apply to a new protocol identifier, that identifier should not be used in TLS configurations where it is clearly visible, and documents specifying such protocol identifiers should recommend avoiding this insecure use.

V. IANA Considerations

IANA has updated its "ExtensionType Values" registry to include the following entry:

      16 application_layer_protocol_negotiation

This document establishes a registry under the existing "Transport Layer Security (TLS) Extensions" heading for protocol identifiers titled "Application-Layer Protocol Negotiation (ALPN) Protocol IDs".

Entries in this registry require the following fields:

  • Protocol: The protocol name.
  • Identification Sequence: A precise sequence of octet values identifying the protocol. This may be the UTF-8 encoding of the protocol name [RFC3629].
  • Reference: A reference to the specification that defines the protocol.

This registry operates under the "Expert Review" policy defined in [RFC5226]. Designated experts are encouraged to include references to stable and readily available specifications that enable interoperable implementations of the identified protocol.

The initial set of registrations in this registry is as follows:

Protocol: HTTP/1.1
Identification Sequence:
0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31 ("http/1.1")
Reference: [RFC7230]

Protocol: SPDY/1
Identification Sequence:
0x73 0x70 0x64 0x79 0x2f 0x31 ("spdy/1")
Reference:
http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft1

Protocol: SPDY/2
Identification Sequence:
0x73 0x70 0x64 0x79 0x2f 0x32 ("spdy/2")
Reference:
http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2

Protocol: SPDY/3
Identification Sequence:
0x73 0x70 0x64 0x79 0x2f 0x33 ("spdy/3")
Reference:
http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3


Reference:

RFC 7301

GitHub Repo: Halfrost-Field

Follow: halfrost · GitHub

Source: https://halfrost.com/tls_alpn/