Google Technical Note - TLS Next Protocol Negotiation
nextprotoneg
July 2011
1
Adam Langley <agl@google.com>

TLS Next Protocol Negotiation

Abstract

This document describes a Transport Layer Security (TLS) extension for application layer protocol negotiation. This allows the application layer to negotiate which protocol should be performed over the secure connection.

Introduction

The Next Protocol Negotiation extension (NPN) is currently used to negotiate the use of SPDY as an application level protocol on port 443, and to perform SPDY version negotiation. However, it is not SPDY specific in any way.

When designing SPDY, we were faced with a problem: there are no good options for establishing a clean transport for a new protocol and negotiating its use. Negotiations on port 80 will run afoul of intercepting proxies. Ports other than 80 and 443 are likely to be firewalled without any fast method of detection, and are also unlikely to traverse HTTP proxies with CONNECT. Using port 443 is possible, but will run afoul of MITM proxies and, also, we didn't want to use a round trip for negotiation on top of the round trips for establishing the TLS connection.

Next Protocol Negotiation allows us to run over port 443, without additional round trips and with fallback in the case of a MITM proxy.

Next Protocol Negotiation Extension

A new extension type (next_protocol_negotiation) is defined with extension type 13172 and MAY be included by the client in its ClientHello message if the ClientHello also includes a server_name_indication extension. If, and only if, the server sees this extension in the ClientHello, it MAY choose to echo the extension in its ServerHello.

The extension_data field of a next_protocol_negotiation extension in a ClientHello MUST be empty.

The extension_data field of a next_protocol_negotiation extension in a ServerHello contains an optional list of protocols advertised by the server. Protocols are named by opaque, non-empty byte strings and the list of protocols is serialized as a concatenation of 8-bit, length prefixed byte strings. Implementations MUST ensure that the empty string is not included and no byte strings are truncated.

A new handshake message type (NextProtocol) is defined with type 67. If, and only if, the server included a next_protocol_negotiation extension in its ServerHello message, the client MUST send a NextProtocol message after its ChangeCipherSpec and before its Finished message.

Therefore a full handshake with NextProtocol has the following flow (contrast with RFC 5246, section 7.3):

Client                                               Server

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

An abbreviated handshake with NextProtocol has the following flow:

Client                                                Server

ClientHello (NP extension)    -------->
                                                 ServerHello (NP extension & list of protocols)
                                          [ChangeCipherSpec]
                              <--------             Finished
[ChangeCipherSpec]
NextProtocol
Finished                      -------->
Application Data              <------->     Application Data

The NextProtocol message has the following format:

struct {
  opaque selected_protocol<0..255>;
  opaque padding<0..255>;
} NextProtocol;

The contents of selected_protocol are a protocol but need not have been advertised by the server. The length of padding should be 32 - ((len(selected_protocol) + 2) % 32). Note that len(selected_protocol) does not include its length prefix.

Unlike many other TLS extensions, this extension does not establish properties of the session, only of the connection. When session resumption or session tickets are used, the previous contents of this extension are irrelevant and only the values in the new handshake messages are considered.

For the same reasons, after a handshake has been performed for a given connection, renegotiations on the same connection MUST NOT include the next_protocol_negotiation extension.

Protocol selection

It's expected that a client will have a list of protocols that it supports, in preference order, and will only select a protocol if the server supports it. In that case, the client SHOULD select the first protocol advertised by the server that it also supports. In the event that the client doesn't support any of server's protocols, or the server doesn't advertise any, it SHOULD select the first protocol that it supports.

There are cases where the client knows that a server supports an unadvertised protocol. In these cases the client should simply select that protocol.

Design discussion

NPN is an outlier from TLS in several respects: firstly that it introduces a handshake message between the ChangeCipherSpec and Finished message, that the handshake message is padded, and that the negotiation isn't done purely with the hello messages. All these aspects of the protocol are intended to prevent middle-ware discrimination based on the negotiated protocol and follow the general principle that anything which can be encrypted, should be encrypted. The server's list of advertised protocols is in the clear as a compromise between performance and robustness.

Known protocols

The following protocol byte strings are, or were, in use:

Implementations

NPN has been implemented in NSS (patch), TLSLite (patch) and OpenSSL (included in CVS, patch against 1.0.0d).

A reference implementation server is running on port 443 of www.google.com. On the client side, the Chrome web browser enables NPN by default.

Magic values

For easy reference, this note uses the following magic numbers:

Next protocol negotiation extension number13172
NextProtocol handshake message number67
Acknowledgments

This document benefited specifically from discussions with Wan-Teh Chang and Nagendra Modadugu.