Subject: [hybi] NPN proposal

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Dec 2010 09:36:46 -0800

I will be writing the following up as a more concrete proposal for a
NPN-based handshake, but wanted to send something out quickly as it seems
timely. The below assumes we can work with the appropriate groups to make
progress on NPN. (I'm no longer convinced that this group is faster moving
than any other.) http://tools.ietf.org/id/draft-agl-tls-nextprotoneg-00.txt

Assumptions:
1. The framing from -03 is good enough.
2. SSL handshake roundtrip is acceptable cost
3. We still want to be able to send headers
 - this includes cookies
 - this includes a resource / path (so we can figure out which backend /
application we are taking about)
 - this includes "Origin"
4. After the SSL handshake we don't want an extra roundtrip if we can avoid
it
5. After SSL+NPN handshake we are sure we are talking to WebSocket endpoint.
6. We assume people can deploy NPN
7. We assume SSL extensions actually work, and available in well known
libraries.
8. We assume ws:// should not require encryption (monitoring software etc
continues to work)
9. We assume we can use :443 for both ws:// and wss://

Proposal:
1. Use -03 framing
2. Add a "Hello" frame type (more detail later) with opcode 0x06
3. In the SSL handshake, use npn("websockets") to indicate that we want to
establish SSL connection
4. For ws://, do not check certificate validity. use NULL
(TLS_RSA_WITH_NULL_SHA?) cipher suite. This still has some overhead but
allows intermediaries such as those deployed at school to look for porn
still function. Encrypting / masking would introduce significant deployment
headaches for such scenarios otherwise.
5. NPN allows for a server to announce things like extensions in the
ServerHello and a client to select. We could use this facility to negotiate
protocol-level extensions (if any).
6. After SSL handshake, we have selected WebSocket extension(s) (if any),
WebSocket extensions (if any).
7. We still need to indicate the resource (ws://google.com/gmail/chat)
somewhere. We also need to include e.g. Cookies. And, if there are any
WebSocket "SubProtocols" we need to indicate those as well. So, let's have
the first thing a client or server sends be a HELLO frame, unfragmented. The
Hello frame in its body includes:
- client: HTTP headers for Origin:, Sec-WebSocket-URL, Cookie:,
Sec-WebSocket-Protocol, X-Whatever-Else
- server: Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
(same as a HTTP response, may include error codes like 403), Set-Cookie,
 X-Whatever-Else
8. Assume after client has sent HELLO, it is free to start sending data. It
doesn't have to wait for server HELLO. Caveat being if the client needs to
negotiate a "subprotocol" then it should wait for that to be echoed in a
server HELLO. (Is anyone actually planning on using SubProtocol?)
9. Server MAY send data immediately after sending Server HELLO, but in
practice it will probably only ever send data after receiving client's first
data frame.

I am happy to write this up in more detail as a formal draft, but I wanted
to at least get this out for discussion as long as other people are
contributing handshake proposals. I personally think such an approach is far
easier to reason about from a security perspective, avoids discussions about
semantics of CONNECT and whether or not UPGRADE is understood by
intermediaries, whether or not we need to do payload masking, etc.

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 18:50:17 +0100

Ian,

for me the big impediment to SSL+NPN is the lack of availability of
NPN on some platforms.

Thus I think it would be good if your proposal could use NPN was used
as an optimization for a handshake that can work over a normal SSL
connection.   Thus if you don't have NPN available, you can still
implement a WS client/server, but will suffer an extra RTT during the
handshake.

cheers

2010/12/21 Ian Fette (イアンフェッティ) <[email-masked]>:
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi
>
>

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Dec 2010 09:54:39 -0800

Hi Greg,

Yes, there is the requirement that NPN be implemented on the platform, which
would necessitate changes. That said, I don't think it's as simple as
"normal SSL connection + handshake" - the handshake would have to be
something that would protect against a non-WebSockets-aware endpoint, which
seems to be something we have been unable to agree upon for the past year :(

The whole point of using NPN was to avoid the need for such a handshake.
Yes, it will require some changes but I'm starting to think it's still a
more plausible approach than trying to design a handshake that will satisfy
the constraints people have set forth.

-Ian

2010/12/21 Greg Wilkins <[email-masked]>

> > than any other.)
> http://tools.ietf.org/id/draft-agl-tls-nextprotoneg-00.txt
> > Assumptions:

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 09:55:07 -0800

2010/12/21 Ian Fette (イアンフェッティ) <[email-masked]>

> Hi Greg,
>
> Yes, there is the requirement that NPN be implemented on the platform,
> which would necessitate changes. That said, I don't think it's as simple as
+1

-Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 18:59:51 +0100

On Tue, Dec 21, 2010 at 09:55:07AM -0800, Eric Rescorla wrote:
> 2010/12/21 Ian Fette (?$B%$%"%s%U%'%C%F%#) <[email-masked]>
> 
> > Hi Greg,
> >

At least we know whose expectations it will satisfy :-/

Willy

---

From: John Tamplin <[email-masked]>
Date: Tue, 21 Dec 2010 13:03:36 -0500

> seems to be something we have been unable to agree upon for the past year :(

I don't think deploying a standard that can't be used for a year or more on
some platforms is realistic either.

For example, AFAIK, there is still no SSL implementation shipping for Java
with SNI support (which would also be required here if we wanted to allow
virtual domains for WebSockets), so there is no telling how long it would be
before something that isn't even standardized yet would take to be
available.

-- 
John A. Tamplin
Software Engineer (GWT), Google

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Dec 2010 10:04:20 -0800

> At least we know whose expectations it will satisfy :-/

I'm not sure what that is supposed to imply, but I was hoping it would
satisfy a broader group of people's expectations. It is much easier to
reason about, it doesn't abuse CONNECT semantics, it doesn't imply payload
masking, etc.

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Dec 2010 10:05:31 -0800

> some platforms is realistic either.

It's already been a year since we took WebSockets to IETF. So, I don't
really see this as an isue.

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 10:07:44 -0800

> At least we know whose expectations it will satisfy :-/

This appears to be some form of weak-ass sarcasm, but I can't imagine why
you think it
has any bite. I said I preferred an NPN-style solution quite some time ago.

-Ekr

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 19:14:04 +0100

> the constraints people have set forth.

OK, then how about at least get a dedicated WS port so that if an SSL
connection comes on that port we can assume that it is WS and
immediately look for the hello frames and if they are present we have
a WS connection.

Without a non-NPN way of accepting WS connections, you will rule all
of java land out of contributing to the testing and development of the
protocol.  Sure it might be available in a year (when this WG might
finally produce), but you can't expect the java world to sit out until
that time.

cheers

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Dec 2010 10:18:45 -0800

> which
If we did a dedicated port in addition to 443 for those who are unable to
use NPN, and we just assume that connections on that port are WS and
immediately look for the HELLO frames, I wouldn't have any objection to
that. We may still have issues with firewall traversals for that though, as
previous experiments have shown poor results with ports other than 443, but
as long as it's a documented "known issue" c'est la vie.

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 19:25:16 +0100

> as long as it's a documented "known issue" c'est la vie.

having issues with 30% of deployed firewalls in production is not
great, but ok at least for development.
having issues with 100% of JVMs in production and development is a non starter.

cheers

---

From: John Tamplin <[email-masked]>
Date: Tue, 21 Dec 2010 13:30:03 -0500

On Tue, Dec 21, 2010 at 1:05 PM, Ian Fette (イアンフェッティ) <[email-masked]>wrote:

> really see this as an issue.
>

Ok, so we ship it and just tell everyone that wants to use a Java-based
server, such as Jetty, Tomcat, and many commercial ones, that they are just
out of luck until Oracle decides to get around to it?  Or alternatively,
that everyone who wants to use WebSockets in Java should just write their
own SSL implemetation?

Even on other platforms you have issues -- say OpenSSL were updated tomorrow
to support NPN.  How long before that was exposed to python SSL libraries,
perl, etc?  Do we just tell everyone not writing C/C++ code they don't
really need WebSockets?

That is my major objection to TLS+NPN, but a secondary one is that we went
to a lot of effort to keep the framing small for small messages and reduce
roundtrips for startup.  Now, we will add at least 20 bytes overhead per
frame and adding a guaranteed round trip during startup.

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 19:30:44 +0100

Hi Ian,

On Tue, Dec 21, 2010 at 10:04:20AM -0800, Ian Fette (????????????????????????) wrote:
> I'm not sure what that is supposed to imply,

Oh I mean that I feel like TLS+NPN has been pushed hard by a small group
for a very long time, and one of the objections at that time was that it
was not ready yet. I sometimes wonder whether the repetitive diversions
from the current drafts are not deliberate attempts to slow down the
process in order to wait for NPN to be ready. And if that's the case, it's
very sad because we could already have released one proposal without it,
and being working on the TLS+NPN one right now. What's even more sad is
that I've been receiving such comments in private for several months, so
I think I'm not the only one to get that feeling. But I may be wrong.

> but I was hoping it would

I agree and I really appreciate how you proposed it. We may have to see
what all those asumptions really mean for implementers and for those who
were trying to save the smallest byte in the stream. But at least it's a
proposal.

Regards,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 10:43:16 -0800

On Tue, Dec 21, 2010 at 10:30 AM, Willy Tarreau <[email-masked]> wrote:

> process in order to wait for NPN to be ready.

And by "repetitive diversions" you mean "demonstrations that the current
drafts are inadequate
and proposals for superior designs"? I guess that's one way to characterize
things.

-Ekr

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Dec 2010 10:45:37 -0800

On Tue, Dec 21, 2010 at 10:30 AM, John Tamplin <[email-masked]> wrote:

>> I don't think deploying a standard that can't be used for a year or more
>>> on some platforms is realistic either.
>>>
>>
> Even on other platforms you have issues -- say OpenSSL were updated
> tomorrow to support NPN.  How long before that was exposed to python SSL
> libraries, perl, etc?  Do we just tell everyone not writing C/C++ code they
> don't really need WebSockets?
>
>
FWIW I believe agl has already contributed NPN support to openssl. Perl has
Crypt::OpenSSL or something (sorry, haven't been a perl guy in a long time),
and there's pyOpenSSL.

> frame and adding a guaranteed round trip during startup.
There's the SSL handshake and the RTs it implies, but after that the
proposal I put forward doesn't add any R/Ts after the SSL handshake if you
don't need to negotiate a WebSockets subprotocol. At least for long-lived
connections the thought of an extra RTT at the start isn't the end of the
world, though it's not optimal. That said, I think many people were always
planning on using the SSL version of WS anyways given the abysmal connect
rates on port 80. (And, if we do a dedicated port without SSL as suggested
earlier in the thread, we would avoid those objections and have a reasonably
similar connect rate to what is achievable on port 80.)

---

From: John Tamplin <[email-masked]>
Date: Tue, 21 Dec 2010 13:50:04 -0500

> Crypt::OpenSSL or something (sorry, haven't been a perl guy in a long time),

But those APIs have to expose the NPN functionality once OpenSSL ships NPN
support, which will take time.  [I don't know how it is implemented, but I
assume there has to be something passed to the API to select which "next"
protocol you want to negotiate].

> don't need to negotiate a WebSockets subprotocol.
>

Right, I am talking about TLS+NPN relative to the other handshakes that have
been proposed.

> At least for long-lived connections the thought of an extra RTT at the
> start isn't the end of the world, though it's not optimal. That said, I
> think many people were always planning on using the SSL version of WS
> anyways given the abysmal connect rates on port 80. (And, if we do a
> dedicated port without SSL as suggested earlier in the thread, we would
> avoid those objections and have a reasonably similar connect rate to what is
> achievable on port 80.)
>

Agreed, which is why that is in my "minor objections" category.

However, I think the inability to deploy it on many platforms is a serious
problem.

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 19:52:05 +0100

On Tue, Dec 21, 2010 at 10:43:16AM -0800, Eric Rescorla wrote:
> drafts are inadequate and proposals for superior designs"?

No, demonstrations that the current drafts were inadequate were fine and
helped move forwards. Using such observations to conclude that it was not
appropriate to follow that direction for a handshake whatever we did with
the payload was border-line. Proposing alternatives from scratch and
claiming them superior despite not matching requirements expressed for
one year on the list does not help at all. That's what I'm saying.

Willy

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 11:17:37 -0800

Needless to say, I don't agree at all with this characterization of the
history.

-Ekr

---

From: Maciej Stachowiak <[email-masked]>
Date: Tue, 21 Dec 2010 11:17:23 -0800

On Dec 21, 2010, at 9:54 AM, Ian Fette (イアンフェッティ) wrote:

> Hi Greg,
> 
> Yes, there is the requirement that NPN be implemented on the platform, which would necessitate changes. That said, I don't think it's as simple as "normal SSL connection + handshake" - the handshake would have to be something that would protect against a non-WebSockets-aware endpoint, which seems to be something we have been unable to agree upon for the past year :(
> 
> The whole point of using NPN was to avoid the need for such a handshake. Yes, it will require some changes but I'm starting to think it's still a more plausible approach than trying to design a handshake that will satisfy the constraints people have set forth.

+1

I was initially skeptical of TLS+NPN as the only approach, as it creates some additional deployment challenges. But it seems that creating a secure non-TLS version of the protocol is harder than initially believed, and is taking quite a bit longer than previously expected.

Regards,
Maciej

---

From: Gabriel Montenegro <[email-masked]>
Date: Tue, 21 Dec 2010 19:28:46 +0000

> appropriate to follow that direction for a handshake whatever we did with the
> payload was border-line. Proposing alternatives from scratch and claiming
> them superior despite not matching requirements expressed for one year on
> the list does not help at all. That's what I'm saying.

No.

Current drafts have NOT been shown to be inadequate. Where is this shown? The paper with Adam, Eric, Collin, et al showed inadequacies in a fictitious version of the handshake that is not actually specified in any draft (it's not even equivalent to the protocol in 03).

Ian put it this way:

http://news.cnet.com/8301-30685_3-20025272-264.html:
"It's important to note that the research paper Adam Barth et al. published does not demonstrate a working attack against the actual Web Socket implementation, but rather against one part [of] the protocol taken in isolation. There are other parts of the protocol that would make an actual attack more complicated in practice. "

---

From: "Simon Pieters" <[email-masked]>
Date: Wed, 22 Dec 2010 04:31:41 +0100

> server HELLO. (Is anyone actually planning on using SubProtocol?)

Currently the client is not allowed to send messages until the connection  
is established. The server needs Origin, URL and subprotocol to decide  
whether to establish the connection. If the client gets 'open' and starts  
sending messages, but the server actually refuses the connection based on  
the information in the Hello frame, then the client will think that the  
connection was first accepted but then dropped.

I think we still need to wait for the server to check Origin, URL and  
subprotocol before saying that the "connection is established".

Would it be possible to smuggle this information somewhere in the TLS  
handshake?

-- 
Simon Pieters
Opera Software

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Dec 2010 20:38:03 -0800

2010/12/21 Simon Pieters <[email-masked]>

> On Tue, 21 Dec 2010 18:36:46 +0100, Ian Fette (イアンフェッティ) <
> [email-masked]> wrote:
>
In the current draft of NPN, the client is basically not allowed to smuggle
any data in the handshake. Adam Langley didn't seem thrilled with the
prospect, though it is possible.

I agree it might be a bit odd to say the websocket is connected, and then
throw an error saying "oops, never mind". We could do it, but it wouldn't be
that clean. A server may also wish to check the cookies before accepting
data. I suppose a server could decide to close the connection based on any
of that data. It's not clear how much we really want to smuggle into the TLS
handshake (cookies, etc?).

Perhaps we end up living with the rtt, though it does seem unfortunate.

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 20:44:15 -0800

> handshake (cookies, etc?).
What's the objection to being allowed to put data in the handshake, given
that TLS extensions in
general provide this facility? [Not saying that we wouldn't need to address
the issue of faux
HTTP traffic in said extension, but that's a separate issue..]

-Ekr

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Dec 2010 21:41:08 -0800

2010/12/21 Eric Rescorla <[email-masked]>

>> In the current draft of NPN, the client is basically not allowed to
>> smuggle any data in the handshake. Adam Langley didn't seem thrilled with
>> the prospect, though it is possible.
>>

I will let Adam tackle that one :)

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Dec 2010 21:48:36 -0800

>> general provide this facility? [Not saying that we wouldn't need to
>> address the issue of faux

One thing that comes to mind though, is that if we are essentially trying to
do a negotiation for things like websocket subprotocol, cookies, etc, and
jam this all into the handshake, it now means that whatever is terminating
the SSL connection has to talk to the application backend to see if it is
willing to speak websocekt protocol x for user with cookie y etc before
completing the handshake. On something that is designed to just terminate
SSL connections and then basically proxy to a backend server, that could be
a rather significant design / performance implication.

---

From: Adam Barth <[email-masked]>
Date: Tue, 21 Dec 2010 23:46:04 -0800

> I will let Adam tackle that one :)

You probably mean Langley, but I can try to answer.  :)

Adam is concerned about intermediaries discriminating against certain
types of TLS traffic based on data sent early in the handshake.  To
me, it seems like NPN could provide the facility and let the "next
protocol" decide whether to use it.

Adam

---

From: Adam Langley <[email-masked]>
Date: Wed, 22 Dec 2010 11:15:34 -0500

> protocol" decide whether to use it.

I'm missing some context here but, yes, that's why NPN doesn't put
data in the ClientHello. Part of the reason that we need NPN is that
TCP port numbers are the subject of so much interference that they are
useless for many people. Repeating that same design seemed unwise.

AGL

---

From: Jamie Lokier <[email-masked]>
Date: Wed, 22 Dec 2010 18:48:21 +0000

John Tamplin wrote:
>    That is my major objection to TLS+NPN, but a secondary one is that we
>    went to a lot of effort to keep the framing small for small messages
>    and reduce roundtrips for startup. Â Now, we will add at least 20
>    bytes overhead per frame and adding a guaranteed round trip during
>    It.

It doesn't add 20 bytes per frame - you should amortise the TLS
overhead over however many WebSocket frames can be batched together.

When the timing is far enough apart that every frame gets TLS
overhead, then the TLS overhead probably doesn't matter - it doesn't
much affect the number of packets sent or radio transmission power.
When they are very close together, they can be batched.

Somewhere in between is probably the worst case.

Bear in mind that TCP/IP over ethernet adds a *minimum* of
20+20+14+4+64 = 122 bytes per packet... sometimes more.
20 bytes looks small in comparison.

This same observation applies to Comet, infinite-stream-of-HTTP-chunks
and infinite-pipeline-of-HTTP-POSTs methods: Framing overhead
amortises, so isn't as big as it first looks.

-- Jamie

---

From: John Tamplin <[email-masked]>
Date: Wed, 22 Dec 2010 14:04:54 -0500

On Wed, Dec 22, 2010 at 1:48 PM, Jamie Lokier <[email-masked]> wrote:

> >    and reduce roundtrips for startup. � Now, we will add at least 20

Given the current JSAPI, it isn't clear that many messages will be
aggregated.  Say JS sends a message -- you can wait for a while before
sending it in hopes of getting another message to go into the same record,
but that adds latency.  Without any way for the app to specify latency
requirements, it seems dangerous to try and do that automatically.

I have no data to back this up, but my hunch is that WebSocket traffic from
JS apps will match one of two use cases:
- a replacement for RPC, so typically a message is sent and then another one
isn't likely to be sent until a response is received
- games, where the client is sending messages on every action or on a timer

It seems to me that either of these provide little opportunity for batching
requests together, and adding latency trying to do so is actively harmful in
the second case.

> 20 bytes looks small in comparison.

But the ones that care the most can fix that by using ROHC.  Also, the cases
where the size matters most, such as mobile, the fact that lower-layer
headers eat up much of the low-power frame size means you need to be more
frugal about the rest, not less.

---

From: Brian Smith <[email-masked]>
Date: Mon, 27 Dec 2010 12:27:48 -0800 (PST)

Maciej Stachowiak wrote:
> > Yes, there is the requirement that NPN be implemented on the
> > platform, which would necessitate changes. That said, I don't think
> > it's as simple as "normal SSL connection + handshake" - the
> > handshake would have to be something that would protect against a
> > non-WebSockets-aware endpoint, which seems to be something we have
> > been unable to agree upon for the past year :(
> >
> > The whole point of using NPN was to avoid the need for such a
> > handshake. Yes, it will require some changes but I'm starting to
> > think it's still a more plausible approach than trying to design a
> > handshake that will satisfy the constraints people have set forth.
> 
> +1
> 
> I was initially skeptical of TLS+NPN as the only approach, as it
> creates some additional deployment challenges. But it seems that
> creating a secure non-TLS version of the protocol is harder than
> initially believed, and is taking quite a bit longer than previously
> expected.

+1.

I would guess this would happen something like this:

1. Publish an RFC for WebSockets without any cross-protocol attack
   prevention mechanism or port 80 overloading mechanism in the
   handshake (no masking, no upgrade, no connect, no get).

2. Publish an RFC reserving the wss:// scheme for said definition
   plus NPN to deploy WebSockets over TLS on port 443.

3. Publish an RFC reserving the ws:// scheme for said definition
   over some newly-reserved port or requiring an explicit port
   number to be specified.

4. Publish an RFC defining a safe mechanism for "upgrading" 
   from HTTP to some other protocol, and reserve wsh:// for
   using this scheme for WebSockets.

Vendors could then choose which of #2, #3, and #4 to support / wait
for.

If #2 and/or #3 are done at the same time as #1, then they could
be merged into the RFC for #1.

Cheers,
Brian