One document matched: draft-snell-httpbis-keynego-00.xml
<?xml version="1.0"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY rfc2119 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml'>
]>
<?rfc toc="yes"?>
<?rfc strict="yes"?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes"?>
<?rfc compact="yes"?>
<rfc category="info" ipr="trust200811" docName="draft-snell-httpbis-keynego-00">
<front>
<title abbrev="application/merge-patch">
HTTP/2.0 Discussion: SPDY In-Session Key Negotiation
</title>
<author initials="J.M." surname="Snell" fullname="James M Snell">
<address>
<email>jasnell@gmail.com</email>
</address>
</author>
<date month="August" year="2012" />
<keyword>I-D</keyword>
<keyword>http</keyword>
<keyword>spdy</keyword>
<abstract>
<t>This memo describes a proposed modification to SPDY that
introduces the concepts of In-Session Key Negotiation and
Secure Framing.</t>
</abstract>
</front>
<middle>
<section title="Introduction">
<t>In-Session Key Negotiation allows endpoints to
dynamically negotiate cryptographic keys after a
SPDY Session has already been established through
the exchange of one or more KEY_NEGO control frames.</t>
<t>There are a number of benefits to such a mechanism:
<list style="numbers">
<t>The ability to negotiate multiple keys over a single
TCP/IP connection.</t>
<t>The ability to renegotiate keys on the fly without
tearing down and reestablishing the TCP/IP connection.</t>
<t>Key Negotiation is intermediary friendly while remaining
secure. Both Hop-by-Hop and End-to-End negotiation schemes
would be possible.</t>
<t>Support for multiple key negotiation mechanisms,
including pre-shared key.</t>
<t>Support for server-initiated key negotiation .. allowing
responses to be secured on-demand by servers even if the client
did not initiate the secure request. This allows servers to
enforce secure communication with the client.</t>
<t>The ability to target specific key negotiations at individual
hosts.</t>
<t>The possibility of using negotiated keys as an
alternative to basic and digest authentication.</t>
</list>
</t>
<t>TODO: More coverage on the needs, benefits</t>
</section>
<section title="In-Session Key Negotiation">
<t>The KEY_NEGO control frame is used to negotiate cryptographic
keys for use by either endpoint within an established SPDY Session.</t>
<figure><preamble>The KEY_NEGO Frame</preamble><artwork>
+---------------------------------+
|1| version | KEY_NEGO |
+---------------------------------+
| Flags (8) | LENGTH (24) |
+---------------------------------|
|X| KEY_ID (31) |
+---------------------------------+
|X| Associated-To-Stream-ID (31) |
+---------------------------------+
| ALG_ID(16) | SEQ(8) | |
+------------------------+ |
| (HEADERS BLOCK) |
| |
</artwork></figure>
<t>Flags: Flags related to this frame. Valid flags are:
<list>
<t>0x01 = FLAG_EXPECTS_RESPONSE - Indicates that the
sender is expecting to receive a KEY_NEGO frame in
response to this one.</t>
<t>0x02 = FLAG_DONE - Indicates that this is the last
KEY_NEGO frame the sender will send for this key
negotiation sequence.</t>
<t>0x04 = FLAG_WAIT - Indicates that the sender will
be sending additional KEY_NEGO frames and that the
recipient should wait for those before responding.</t>
<t>0x08 = FLAG_ERROR - Indicates that an error has
occurred within the key negotiation sequence and that
the headers contains the details of the error.</t>
<t>0x10 = FLAG_VOID - Indicates that the sender
wishes for a previously negotiated key to be voided,
making it unavailable for further use within the
same SPDY Session.</t>
</list>
</t>
<t>Length: The length is the number of bytes which follow
the length field in the frame. For KEY_NEGO frames, this is
7 bytes plus the length of Headers block.</t>
<t>KEY_ID: The 31-bit identifier for the key being
negotiated. KEY_NEGO frames initiated by the client
MUST have an odd-numbered ID. KEY_NEGO frames initiated
by the server MUST have an even-numbered ID.</t>
<t>Associated-To-Stream-ID: The 31-bit identifier for a
Stream for which this key is to be associated. If this
key is independent of all other streams, it should be 0.</t>
<t>If a key is associated with a given stream, the key
is destroyed when the stream is concluded.</t>
<t>ALG_ID: The 16-bit identifier of the key negotiation
algorithm being performed.</t>
<t>SEQ: An 8-bit unsigned integer incremented for each
KEY_NEGO frame exchanged for a given KEY_ID.</t>
<t>HEADERS BLOCK: The block of headers carried as part
of the KEY_NEGO frame.</t>
<t>Within any single SPDY session, multiple KEY_NEGO
exchanges may occur. However, once the range of possible
KEY_ID's has been exhausted, no further negotiation is
possible within that session.</t>
</section>
<section title="Secure Framing">
<t>Obviously, negotiating a key is pointless if it cannot
be subsequently used to secure communications. For this,
we can either modify the existing SPDY frames defined in
[draft-mbelshe-httpbis-spdy-00] or introduce additional
extension Control Frames. Currently, this memo
adopts the latter approach.</t>
<t>Three new Control Frames would be introduced:
<list style="symbols">
<t>SYN_SEC_STREAM</t>
<t>SYN_SEC_REPLY</t>
<t>INTEGRITY</t>
</list>
</t>
<t>The SYN_SEC_STREAM and SYN_SEC_REPLY control frames
are generally identical to the existing SYN_STREAM and
SYN_REPLY frames, but include an additional 31-bit
KEY_ID field that identifies the negotiated key used to
encrypt the contents of both the block of headers
(within the SYN_* frame as well as subsequent HEADERS
frames) and all data frames within the stream.</t>
<figure><preamble>SYN_SEC_STREAM Control Frame:</preamble><artwork>
+------------------------------------+
|1| version | SYN_SEC_STREAM |
+------------------------------------+
| Flags (8) | Length (24 bits) |
+------------------------------------+
|X| Stream-ID (31bits) |
+------------------------------------+
|X| Associated-To-Stream-ID (31bits) |
+------------------------------------+
| Pri|Unused | Slot |X| KEY_ID (31) |
+------------------------------------|
| (Headers Block) |
| ... |
</artwork></figure>
<figure><preamble>SYN_SEC_REPLY:</preamble><artwork>
+------------------------------------+
|1| version | SYN_SEC_REPLY |
+------------------------------------+
| Flags (8) | Length (24 bits) |
+------------------------------------+
|X| Stream-ID (31bits) |
+------------------------------------+
|X| KEY-ID (31) |
+------------------------------------+
| (Headers Block) |
| ... |
</artwork></figure>
<t>Additional, a new Stream Integrity Control frame
is proposed that allows a sender to periodically insert
a checksum into the stream. The checksum is calculated
over the bytes of all HEADERS and Data frames sent since
(and including) the initial SYN_* control frame or the
previously sent INTEGRITY frame. If a key is used to
generate the digest, the KEY_ID field can be used to
reference the key. If the SYN_SEC_STREAM or SYN_SEC_REPLY
contained a KEY_ID, then the digest is encrypted using
the identified key..</t>
<figure><preamble>INTEGRITY Frame:</preamble><artwork>
+----------------------------------+
|0| version | INTEGRITY |
+----------------------------------+
|X| Stream-ID (31bits) |
+----------------------------------+
|X| KEY-ID (31bits) |
+----------------------------------+
| ALG_ID (8) | SEQ(8) |Length (24) |
+----------------------------------+
| Digest |
+----------------------------------+
</artwork></figure>
<t>If the recipient receives an INTEGRITY frame that does
not validate, it can choose to terminate the stream with a
RST_STREAM.</t>
</section>
<section title="Example: Pre-shared Secret Key">
<t>Consider a scenario where user, Tom, is accessing
a service on host "example.org". As part of
the out of band registration process, a shared secret
key is generated and shared by Tom and the hosted
service. This key is tied to Tom's user account name:
"tom".</t>
<t>In this example, only a single KEY_NEGO frame needs
to be exchanged, sent by Tom to the Server to identify
the name of the pre-shared key.</t>
<figure><artwork>
Tom Server
| |
|=====================>|
| 1) SYN |
|<=====================|
| 2) SYN_ACK |
|=====================>|
| 3) ACK |
| |
|=====================>|
| 4) KEY_NEGO |
| ID=1 |
| ALG_ID=1 (PSK) |
| FLAGS=0x02 |
| SEQ=1 |
| :host=example.org |
| :key=tom |
| |
|=====================>|
| 5) SYN_SEC_STREAM |
| ID=1 |
| KEY_ID=1 |
| :method=POST |
| :host=example.org |
| |
|=====================>|
| 6) DATA |
| ID=1 |
| (encrypted data) |
| |
| ...
</artwork></figure>
<t>The SYN_SEC_STREAM establishes a secured stream
that references the established key, and all headers
and data transmitted would be encrypted using the
identified key.</t>
<t>The server MAY choose to respond with either a
SYN_REPLY or SYN_SEC_REPLY.</t>
</section>
<section title="Example: Diffie-Helmman Exchange">
<t>Multi-step key negotiation mechanisms, such as
the popular Diffie-Hellman mechanism, can also be
implemented through the exchange of multiple
KEY_NEGO frames.</t>
<figure><artwork>
Tom Server
| |
|=====================>|
| 1) SYN |
|<=====================|
| 2) SYN_ACK |
|=====================>|
| 3) ACK |
| |
|=====================>|
| 4) KEY_NEGO |
| ID=1 |
| ALG_ID=2 (DH) |
| FLAGS=0x01 |
| SEQ=1 |
| :host=example.org |
| :p={p} |
| :g={g} |
| :A={A} |
| |
|<=====================|
| 5) KEY_NEGO |
| ID=1 |
| ALG_ID=2 (DH) |
| FLAGS=0x02 |
| SEQ=2 |
| :B={B} |
| |
|<====================>|
| STREAM / REPLY |
| (secured w/Key 1) |
| |
</artwork></figure>
</section>
<section title="Example: In-Session TLS">
<t>KEY_NEGO frames can even be orchestrated to mimic
the existing TLS-Handshake protocol:</t>
<figure><artwork>
Tom Server
| |
|=====================>|
| 1) SYN |
|<=====================|
| 2) SYN_ACK |
|=====================>|
| 3) ACK |
| |
|=====================>|
| 4) KEY_NEGO | // CLIENT_HELLO
| ID=1 |
| ALG_ID=3 (IS-TLS) |
| FLAGS=0x01 |
| SEQ=1 |
| :host=example.org |
| :gmt_unix_time={X} |
| :random:... |
| :session:... |
| :ciphers:... |
| :extensions:... |
| |
|<=====================|
| 5) KEY_NEGO | // SERVER_HELLO
| ID=1 |
| ALG_ID=3 |
| FLAGS=0x04 |
| SEQ=2 |
| :random:... |
| :session:... |
| :cipher:... |
| :extensions:... |
| :cert:... |
| ... | <==| Certificate
| | <==| ServerKeyExchange
| | <==| CertificateRequest
|<=====================|
| 6) KEY_NEGO | // SERVER_FINISHED
| ID=1 |
| ALG_ID=3 |
| FLAGS=0x2 |
| | |==> Certificate
| | |==> ClientKeyExchange
| | |==> CertificateVerify
| | <==> Change Cipher Spec
|=====================>|
| 7) KEY_NEGO | // CLIENT_FINISHED
| ID=1 |
| ALG_ID=3 |
| FLAGS=0x2 |
| |
|<====================>|
| STREAM / REPLY |
| (secured w/Key 1) |
| |
</artwork></figure>
</section>
<section title="Example: Server-Initiated Key Exchange">
<t>One of the more interesting cases enabled by
In-Session Key Negotiation is the possibility of
server-initiated protection. That is, if a client
opens an insecured stream with the server, the
server could choose to upgrade that stream on-the-fly
by initiating a KEY_NEGO exchange and responding
with a SYN_SEC_REPLY. All content returned by the
server would be encrypted, even if the request was
not.</t>
<figure><artwork>
Tom Server
| |
|=====================>|
| 1) SYN |
|<=====================|
| 2) SYN_ACK |
|=====================>|
| 3) ACK |
| |
|=====================>|
| 4) SYN_STREAM |
| ID=1 |
| :method=GET |
| :path=/ |
| :host=example.org |
| |
|<=====================|
| 5) KEY_NEGO |
| ID=2 |
| ASSOC_STREAM_ID=1 |
| ALG_ID=1 |
| FLAGS=0x2 |
| :key="tom" |
| |
|<=====================|
| 6) SYN_SEC_REPLY |
| ID=1 |
| KEY_ID=2 |
| ... |
| |
</artwork></figure>
</section>
<section title="Security Considerations">
<t>TBD. TODO: Need to expand this...</t>
<t>Negotiated Keys should likely be tied to a
same-origin policy. The same negotiated key
could not be used with multiple origins... instead,
require the client to negotiate a separate key
for each origin unless the specific key negotiation
protocol allows multi-origin operation.</t>
</section>
</middle>
<back>
<references title="Normative References">
&rfc2119;
</references>
</back>
</rfc>
| PAFTECH AB 2003-2026 | 2026-04-24 05:40:08 |