One document matched: draft-snell-httpbis-keynego-02.xml
<?xml version="1.0"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY rfc2119 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml'>
<!ENTITY rfc6454 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.6454.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-02">
<front>
<title abbrev="HTTP/2.0 Intra-Connection Negotiation">
HTTP/2.0 Intra-Connection Negotiation
</title>
<author initials="J.M." surname="Snell" fullname="James M Snell">
<address>
<email>jasnell@gmail.com</email>
</address>
</author>
<date month="November" year="2013" />
<keyword>I-D</keyword>
<keyword>http</keyword>
<keyword>spdy</keyword>
<abstract>
<t>
This memo describes a proposed modification to HTTP/2.0 that
introduces the concepts of Intra-Connection Negotiation
and Secure Framing.</t>
</abstract>
</front>
<middle>
<section title="Introduction">
<t>
HTTP/2.0 Intra-Connection Negotiation allows peers to
dynamically negotiate agreements (e.g. for cryptographic keys) with
an origin (as defined by <xref target="RFC6454" />) from within an
established HTTP/2.0 connection.
</t>
<t>
This mechanism would provide a number of important benefits,
including:
<list style="numbers">
<t>
The ability to negotiate multiple agreements for one or more
origins within a single HTTP/2.0 connection;
</t>
<t>
The ability to revoke and renegotiate agreements on the fly
without tearing down and reestablishing the HTTP/2.0
connection;
</t>
<t>
Support for multiple negotiation mechanisms,
including pre-shared key, etc;
</t>
</list>
</t>
</section>
<section title="Agreement Negotiation">
<t>
Intra-Connection Negotiation is facilitated through the
use of a new "NEGOTIATE" HTTP pseudo-method. The HTTP header
field mapping for the NEGOTIATE method works similarly to
that of CONNECT methods, with a few notable exceptions:
<list style="symbols">
<t>The ":method" header field is set to "NEGOTIATE".</t>
<t>The ":scheme" and ":path" header fields MUST be omitted.</t>
<t>
The ":authority" header field contains the host and port
of the origin for which an agreement is being negotiated.
</t>
<t>
An ":id" header field MUST be given specifying the
31-bit numeric identifier of the agreement being negotiated.
</t>
<t>
An ":algorithm" header field MUST be given specifying the
IRI identifier of the negotiation / agreement algorithm
being utilized.
</t>
</list>
</t>
<t>
A complete negotiation consumes a single stream within a connection
and may consist of one or more distinct "messages" exchanged within
that stream. The number of messages required for a negotiation depends
on the specific algorithm being used. On HEADERS and DATA frames, the
currently reserved 0x2 flag is used to signal the end of individual
messages. The negotiation is considered complete when the stream is
closed. A negotiated agreement cannot be used until the negotiation for
is completed.
</t>
<section title="Example: Pre-Shared Key">
<t>
To illustrate the basic flow of the negotiation protocol,
consider the simple case where both peers share a common
pre-shared secret. To simplify the example, we assume that
there is need to prove possession of the shared secret.
</t>
<t>
The initiating peer would send:
</t>
<figure><artwork>
HEADERS
END_STREAM (0x1)
END_MESSAGE (0x2)
END_HEADERS (0x4)
:method = NEGOTIATE
:authority = example.org
:id = 1
:algorithm = urn:example:algorithm:psk
name = Our Shared Key Name
</artwork></figure>
<t>
The flags END_STREAM and END_MESSAGE indicate to the receiving
peer that no additional messages will be sent for this negotiation.
Assuming the negotiation is accepted, a simplified response would be:
</t>
<figure><artwork>
HEADERS
END_STREAM (0x1)
END_MESSAGE (0x2)
END_HEADERS (0x4)
:status = 200
</artwork></figure>
</section>
<section title="Example: Multi-step Negotiation">
<t>
Some negotiation algorithms require multiple steps.
This is accomplished by exchanging multiple messages within
a single stream.
</t>
<t>
A "message" consists of a combination of a HEADERS frame
followed by zero or more DATA frames. The last frame in the
message MUST have the END_MESSAGE flag set.
</t>
<figure><preamble>Initializing a multi-step negotiation (note that the END_STREAM flag is not set)</preamble><artwork>
HEADERS
END_MESSAGE (0x2)
END_HEADERS (0x4)
:method = NEGOTIATE
:authority = example.org
:id = 1
:algorithm = urn:example:algorithm:multistep
init-param-1 = foo
</artwork></figure>
<figure><preamble>The initializing reponse (again, note that the END_STREAM flag is not set)</preamble><artwork>
HEADERS
END_MESSAGE (0x2)
END_HEADERS (0x4)
:status = 200
init-param-A = bar
</artwork></figure>
<t>
Once the initial HEADERS frames are sent, the peers are free to
exchange as many messages on the stream as necessary to complete
the negotiation process. When a peer is done with it's part of
the negotiation, it will include the END_STREAM flag on the last
frame it sends. If the negotiation process fails after the initial
HEADERS frames are sent, an RST_STREAM frame is used to terminate
the negotiation process.
</t>
</section>
</section>
<section title="Secure Framing (Option 1)">
<t>
Obviously, negotiating an agreement is pointless if it cannot
be subsequently used. To that end, I propose a modification to the
existing DATA frame definition.
</t>
<t>
Specifically, I propose the introduction of a new AGREEMENT
flag (0x4). When set, the flag indicates that the first
four bytes of the DATA frame payload specify a numeric
agreement identifier, and that the remaining DATA frame payload
has been constructed in accordance with the referenced agreement.
They specific structure of that data depends entirely on
the properties of the agreement identified.
</t>
<figure><artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|X| Agreement ID (31) |
+-+-------------------------------------------------------------+
| Protected Payload Data ...
+---------------------------------------------------------------+
</artwork></figure>
</section>
<section title="Secure Framing (Option 2)">
<t>
A potential alternative (and likely better) option for use
of a negotiated agreement is to move agreement identification
out of the DATA frame and into a request header field. For
instance:
</t>
<figure><artwork>
HEADERS
:method = POST
:authority = example.org
:agreement = 1
</artwork></figure>
<t>
The presence of the ":agreement" header field in the initial HEADERS
block indicates that all frames transmitted on the stream (in the same
direction) are constructed in accordance to the specified agreement.
</t>
</section>
<section title="Renegotiation of Agreements">
<t>
Depending on the nature of the agreement, it might be possible
for the requesting peer to renegotiate an agreement with the
origin. Significant care should be taken here, however, to
prevent the possibility of downgrade attacks.
</t>
<t>
Renegotiation occurs by initiating a new NEGOTIATE request
specifying an already established agreement identifier. This
new interaction could establish new properties, expectations,
etc for the agreement. The renegotiation is not complete
until after both peers successfully close the stream, meaning any
new negotiated properties do not become effective until after
renegotiation is complete.
</t>
</section>
<section title="Explicit Termination of Agreements">
<t>
It is possible that a mechanism for explicitly revoking or
terminating an agreement will be needed in some scenarios.
Termination of an agreement is essentially a form of
renegotiation and would happen following a similar approach.
One possible method for terminating an agreement would be
to send something like the following:
</t>
<figure><artwork>
HEADERS
:method = NEGOTIATE
:id = 1
:algorithm: urn:example:algorithm:revoke-agreement
</artwork></figure>
<t>
A downside of this, however, termination would require
action on the part of the requesting peer and could
not be initiated by the origin unless we allow the
origin to PUSH_PROMISE NEGOTIATE methods (which has it's
own distinct problems since a client cannot send on a
pushed stream).
</t>
</section>
<section title="The INTEGRITY frame type">
<t>
The INTEGRITY frame (type=0xB) allows a sending peer to insert
periodic message authentication codes (MACs) into a stream to
provide integrity and authenticity of a streams content.
</t>
<figure><artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| MAC (*) ...
+---------------------------------------------------------------+
</artwork></figure>
<t>
The INTEGRITY frame defines the following flags:
<list style="hanging">
<t hangText="END_STREAM (0x1):">
Bit 1 being set indicates that this frame is the last that
the endpoint will send for the identified stream. Setting
this flag causes the stream to entire one of "half closed"
states or "closed" state.
</t>
</list>
</t>
<t>
The payload of the INTEGRITY frame consists of a MAC calculated
over the payloads of all other frames sent on a stream since either
the stream was opened or a previous INTEGRITY frame was sent.
</t>
<t>
INTEGRITY frames MUST be associated with a stream that is, in turn,
associated with a negotiated agreement. The algorithm used to
gernerate the MAC is determined entirely through use of the
NEGOTIATE pseudo-method.
</t>
</section>
<section title="Secure Tunneling with CONNECT">
<t>
Obviously, the approach described thus far only secures
the content of DATA frames. With HTTP, however, there is
a significant amount of sensitive content carried within
HEADERS frames. To provide a more complete solution,
the mechanisms described herein can be combined with the
CONNECT method to create a secure tunnel. Specifically:
<list style="symbols">
<t>
First, use the NEGOTIATE method to negotiate an
agreement with an origin,
</t>
<t>
Second, use the CONNECT method to establish a
tunnel through that origin,
</t>
<t>
Third, use SECURED DATA frames over the connected
tunnel.
</t>
</list>
</t>
<figure><artwork>
HEADERS
END_STREAM
:method = NEGOTIATE
:authority = example.org
:id = 1
...
HEADERS
:method = CONNECT
:authority = example.org
:agreement = 1
DATA
{Protected Data}
INTEGRITY
{Mac}
DATA
{Protected Data}
...
</artwork></figure>
</section>
<section title="Security Considerations">
<t>TBD. TODO: Need to expand this...</t>
</section>
</middle>
<back>
<references title="Normative References">
&rfc2119;
&rfc6454;
</references>
</back>
</rfc>
| PAFTECH AB 2003-2026 | 2026-04-24 05:38:57 |