- From: James M Snell <jasnell@gmail.com>
- Date: Fri, 13 Jul 2012 14:19:17 -0700
- To: ietf-http-wg@w3.org
This idea was born in a separate thread, wanted to pull it out here so as not to sidetrack the other discussion too much and to get the idea out for discussion. This is, more or less, a data dump of sorts. May be a bit disorganized but, again, the idea is just to get things rolling for discussion purposes. Side note: I am currently engaged in this discussion as an individual and the ideas expressed here should be considered to be based on my own personal thoughts and opinions and not those of my employer. As yet, my employer has not yet officially weighed in the discussions around HTTP/2.0. Basic Premise: The revised framing model used with SPDY provides us with an opportunity to provide support for stream-level protection of data without requiring TLS. Doing so helps routers and intermediaries do their job more efficiently while protecting the confidentiality of data in transit. The proposal below introduces the concept of a new KEY_NEGO frame for SPDY and proposes modified Data and Headers Frame formats to support in-stream, per-frame encryption. KEY_NEGO Control Frame +----------------------------------+ |1| version | KEY_NEGO | +----------------------------------+ | Flags (8) | Length (24 bits) | +----------------------------------+ | ID | ALG_ID | Data | +----------------------------------+ KEY_NEGO Frames are used to negotiate keys for use within a SPDY session. The ID is an 8-bit identifier uniquely identifying the negotiated key within the session. KEY_NEGO Frames initiated by the server must have an even ID KEY_NEGO Frames initiated by the client must have an odd ID If client receives a KEY_NEGO Frame containing an odd ID that it did not initiate, it must ignore the KEY_NEGO frame Likewise, if server receives a KEY_NEGO Frame containing an even ID that it did not initiate, it must ignore the KEY_NEGO frame The ID does NOT recycle... once the range of key IDs available for a given connection have been exhausted, no further key_negotiation is possible. It is possible for a particular Key ID to be renegotiated... The ALG_ID is an unsigned 16-bit identifier specifying the specific key negotiation algorithm in use. If the value is 0x1, then an extension algorithm is being used (see below). All other values > 0x1 shall identify specifically registered key negotiation algorithms. The structure of the Data field depends entirely on the ALG_ID. If ALG_ID == 0x1, then the structure of Data is: +-----------------------------+ | Name Length (int32) | Name | +-----------------------------+ | Data | +-----------------------------+ Where the Name Length is the length, in octets of the Name field. The Name field specifies the name of key negotiation algorithm. The Remaining Data field contains the detail specific to the type of key negotiation. This approach allows us to optimize for the most common cases while supporting extension mechanisms as well. Once the Key Negotiation is complete, the ID of the KEY_NEGO frame becomes the identifier for the Key whenever used within the SPDY session. If Key Negotiation involves multiple steps, each subsequent KEY_NEGO frame will use the same ID. The specific number of KEY_NEGO frames necessary to negotiate a single Key depends on the algorithm used. For each data or control frame, the flag 0x4 indicates that the frame is encrypted. An additional, optional KEY_ID field would need to be added to each frame that supports encryption. Candidates are: Encryption-Supported Data Frame: +----------------------------------+ |C| Stream-ID (31bits) | +----------------------------------+ | Flags (8) | KEY_ID | Length (24) | +----------------------------------+ | Data | +----------------------------------+ Encryption-Supported Headers Frame: +------------------------------------+ |1| version | 8 | +------------------------------------+ | Flags (8) | KEY_ID | Length (24) | +------------------------------------+ |X| Stream-ID (31bits) | +------------------------------------+ | Number of Name/Value pairs (int32) | <+ +------------------------------------+ | | Length of name (int32) | | This section is the "Name/Value +------------------------------------+ | Header Block", and is compressed. | Name (string) | | +------------------------------------+ | | Length of value (int32) | | +------------------------------------+ | | Value (string) | | +------------------------------------+ | | (repeats) | <+ The KEY_ID is the 8-bit identifier of the key previously negotiated using a KEY_NEGO frame. If a frame uses a KEY_ID that has not yet been negotiated fully, decryption of the frame becomes impossible and the receiver can reject it.. possibly by closing the stream. Example: Assume a preshared key is being used, identified using the name "ourkey", assume ALG_ID=2 means "pre-shared key", where Data is the US-ASCII encoded name of the key. [Connection is opened] [Client sends a KEY_NEGO with ID=1,ALG_ID=2,Data="ourkey"] [Client sends SYN_STREAM to open the stream] [Client sends Encrypted Data Frame referencing KEY_ID=1] [Server sends Encrypted Data Frame referencing KEY_ID=1] [Connection is closed] Any intermediary in the flow can participate in the Key Negotiation. For example, suppose client A opens a connection with Server C via intermediary B. Assume that A and B have a preshared key [A opens a connection with B] [A sends a KEY_NEGO with ID=1, ALG_ID=2,Data="ourkey"] [A sends SYN_STREAM to open the stream] [B routes SYN_STREAM to C] [A sends encrypted header and data frames to B referencing KEY_ID=1] [B decrypts the frames, and forwards the frames in clear text to C] This provides us with the same basic benefits as TLS termination at intermediaries. One key question that arises is how B would know that it should decrypt the frame and send it to C in plain text rather than simply forwarding it on in an encrypted state. What I imagine is that would largely just be a matter of configuration for each route. There are a variety of additional advantages to this approach... 1. When a user-agent requires the ability to communicate with two hosts at the same location, and chooses to do so using a single connection, it is possible for the user-agent to negotiate a unique key for each host while still interleaving frames for each host within the same multiplexed connection. Example: [Connection is opened] [Client sends KEY_NEGO with ID=1, ALG_ID=2,Data="host_1_key"] [Client sends KEY_NEGO with ID=2, ALG_ID=2,Data="host_2_key"] [Client sends SYN_STREAM to open the stream with Host_1] [Client sends SYN_STREAM to open the stream with Host_2] [Client sends encrypted header and data frames to Host_1 referencing KEY_ID=1] [Client sends encrypted header and data frames to Host_2 referencing KEY_ID=2] [Host_1 sends encrypted header and data frames to Client referencing KEY_ID=1] [Host_2 sends encrypted header and data frames to Client referencing KEY_ID=2] [Connection is Closed] 2. Encrypted-content over Unsecured Transport... For example: a user is accessing his bank account using their mobile device. The user-agent opens a single unsecured connection to the banks server, over which requests for unsecured static resources are retrieved. The user needs to securely log in to their account. Using KEY_NEGO, the user-agent can negotiate a secured stream using the same connection, passing the encrypted authentication credentials along without the need to set up an expensive, separate TLS-secured connection. Example: [Connection is opened] [Client sends SYN_STREAM to open Stream_1] [Client sends clear-text header and data frames over Stream_1] [Client sends KEY_NEGO with ID=1, ALG_ID=2,Data="ourkey"] [Client sends SYN_STREAM to open Stream_2] [Client sends clear-text header and data frames over Stream_1] [Client sends encrypted header and data frames over Stream_2 referencing KEY_ID=1] [Connection is Closed] 3. Keys can be renegotiated on the fly without tearing down and reestablishing the connection or requiring a new connection to be established. For example, suppose a server or client determines that a particular type of request requires a greater level of encryption than what was originally established for the stream. The intermediary can attempt to renegotiate the key or negotiate a new key to handle the new requirements. Example: [Connection is opened] [Client sends SYN_STREAM to open Stream_1] [Client sends clear-text header and data frames over Stream_1] [Server sends KEY_NEGO with ID=1, ALG_ID=2,Data="ourkey"] [Server sends clear-text header and data frames over Stream_1 to client] [Connection is Closed] 4. Depending on the specific details of the Key_Nego algorithm used, Key negotiation frames can be interleaved with data and control frames. For instance, suppose that a particular Key_nego algorithm requires multiple steps... to use a simple example, let's just say we're using DH for the key_nego, the sender can perform their half of the key_nego and prepare an encrypted data frame... sending it along with the KEY_NEGO for the receiver to process. Example: (Assume ALG_ID=3 refers to something like DH Key nego) [Connection is opened] [Client sends SYN_STREAM to open Stream] [Client sends KEY_NEGO with ID=1, ALG_ID=3,Data={key nego params}] [Client sends encrypted header and data frames referencing KEY_ID=1] [Server sends KEY_NEGO with ID=1, ALG_ID=3,Data={key nego response params}] [Server sends encrypted header and data frames referencing KEY_ID=1] [Connection is Closed] 5. Multiple keys with different strengths can be negotiated within a single connection, allowing for higher-priority frames to use stronger protection than lower-priority frames. Example: For example, suppose that the second Data frame contains financial transaction information that requires higher security [Connection is opened] [Client sends a KEY_NEGO with ID=1,ALG_ID=2,Data="weakkey"] [Client sends a KEY_NEGO with ID=2,ALG_ID=2,Data="strongkey"] [Client sends SYN_STREAM to open the stream] [Client sends Encrypted Data Frame referencing KEY_ID=1] [Client sends Encrypted Data Frame referencing KEY_ID=2] [Connection is closed] 6. With this approach, for many scenarios, use of TLS/SSL could potentially be eliminated altogether. As always, thoughts/opinions/gripes/praise are welcome... - James
Received on Friday, 13 July 2012 21:20:06 UTC