Subject: should we specify HTTP/1.1 now that HTTP2 is out?

From: Michael Richardson <[email-masked]>
Date: Tue, 03 Oct 2017 17:58:11 -0400

I'm seeking guidance.  It might be that this is a job for lwig, or perhaps
there is already a document which details how to do the profiling I care
about.  If so, please point me at that.

In ANIMA's BRSKI protocol, which is based upon RFC7030 EST, we run over HTTP
1.1 today using a single TCP connection.
It's HTTP over TLS ("HTTPS") [h2c?] rather than an upgrade.

In BRSKI there are state issues with both the TLS and the HTTP process.
The TLS server certificate is not trusted by the client until after at least
one RESTful interaction occurs.  Only once that has occured is the connection
considered secure.

We are concerned about how the protocol could become broken if used with
HTTP2 with interleaving of requests/responses.   With HTTP (port-80)
transactions, using the RFC7540 section 3.2 upgrade, one could just decline
to ever do the upgrade and be done.  With HTTPS, this is negotiated in
the TLS connection, so one can go to HTTP2 directly, I think.

While limiting ourselves to HTTP/1.1 might be a good policy, I worry that
at some point in 10 years, the HTTP/1.1 code might be in the library only to
support our use case, with the application code on the device having moved on
to HTTP2 only.

What I think we are looking for is a set of things we can specify that
will make HTTP2 as deterministic (and slow!) as HTTP/1.1. For instance,
I think that
        SETTINGS_MAX_CONCURRENT_STREAMS = 1

would do 90% of it.  Should we turn off PUSH?
Can/should we recommend lower values for window sizes, etc?
(ANIMA end points are not constrained in the IoT/RFC7228 sense, but rather
are control plane CPUs, with megabytes of ram, often partitioned at boot
time.  But, ANIMA BRSKI may also applies to Web connected devices like the
baby monitors that have wreaked havoc.)

--
Michael Richardson <[email-masked]>, Sandelman Software Works
 -= IPv6 IoT consulting =-

---

From: Martin Thomson <[email-masked]>
Date: Tue, 3 Oct 2017 15:07:22 -0700

Are you looking to *standardize* these restrictions, or are you just
asking what is possible?

It's certainly possible to limit the number of concurrent streams,
disable push, constrain flow control aggressively, and other things.
Baking that into a standard would be unwise.

If you are using HTTP and your protocol breaks when requests are sent
and handled concurrently, that might indicate a problem with the usage
and not something that you want to solve in the way you are
suggesting.

---

From: Michael Richardson <[email-masked]>
Date: Tue, 03 Oct 2017 19:49:54 -0400

> Are you looking to *standardize* these restrictions, or are you just

Ideally, I'd reference a document which was something like "restricted http2"
or "http2 dumbed down to http1.1" or "http2 lite" or some such.
That document would get updated now and then to accomodate new issues.

    > and not something that you want to solve in the way you are

We need one request to go through first, and then more or less, the rest
could be handled concurrently.

This is not really any different than the need to login to a web site
before you start making API requests.  Of course, the unauthorized requests
will return 401 or some such,  but it would be better not to confuse the
client which might think it's already done the authentication.

Really, it's all solvable up in the client with a state machine above HTTP2.
I'm just concerned that there might be things that HTTP2 might permit to
occur concurrently (that I don't know about, or maybe hasn't been defined
yet...) that HTTP1.1 would have serialized and not surprised anyone.

Let me know if I'm worried for naught.

---

From: Martin Thomson <[email-masked]>
Date: Tue, 3 Oct 2017 17:15:18 -0700

> That document would get updated now and then to accomodate new issues.

We do have a draft of that document, but it would need more effort to
turn into something that could be referenced.  See
https://datatracker.ietf.org/doc/html/draft-montenegro-httpbis-h2ot-profile

> could be handled concurrently.

So wait for the first request to complete before making the others.
I'm not sure that I see the problem here.

---

From: Patrick McManus <[email-masked]>
Date: Tue, 3 Oct 2017 20:43:37 -0400

it sounds like you've built some kind of implicit ambient authority into
the connection after the first request/response occurs.. that kind of
connection based auth is a bit of an anti-pattern in the http world. (I was
going to say despite a couple prominent examples, but actually it might be
because of a couple prominent examples). You really have very little
control over what actual tcp connections individual transactions occur on
in an end-to-end sense when you take into consideration (forward and
reverse) proxies including things like Anti-Virus MITMs - the connection
can't do a good job of conveying state.

For similar reasons, SETTINGS based profiles aren't going to be especially
effective - SETTINGS is hop to hop and profiling a whole server (instead of
the URIs used for your application) means the origin can't serve anything
else (efficiently).  Also consider h1 pipelines which might very well mean
your existing approach doesn't have the synchronization point you were
hoping for.

Given all of that, you're much better building a session mechanism at the
application level.. as ugly as cookies are, they are the typically way to
do that in a consistent manner in both h1 and h2. That's going to be way
more robust (and performant) in the long run.

hope that helps.

---

From: Lloyd Wood <[email-masked]>
Date: Wed, 4 Oct 2017 01:34:49 +0000 (UTC)

Based on experience, I would say that the state issues
will likely occur with TCP accelerators over a satellite
link.

HTTP/1.1 isn't as deterministic as you would like to
think once an accelerator with prefetching is involved,
and this can break the assumptions of security protocols
layered over HTTP/1.1.

If you're really properly RESTful, this shouldn't be
an issue, of course...
 
Lloyd Wood [email-masked] http://about.me/lloydwood 

________________________________
From: Michael Richardson <[email-masked]>
To: [email-masked] 
Sent: Wednesday, 4 October 2017, 8:58
Subject: should we specify HTTP/1.1 now that HTTP2 is out?

considered secure.

to HTTP2 only.

I think that

--

---

From: Eliot Lear <[email-masked]>
Date: Wed, 4 Oct 2017 06:53:50 +0200

This is properly RESTful.

---

From: Toerless Eckert <[email-masked]>
Date: Wed, 4 Oct 2017 21:15:23 +0200

On Tue, Oct 03, 2017 at 08:43:37PM -0400, Patrick McManus wrote:
...
> more robust (and performant) in the long run.

AFAIK, even secure cookies depend on trust in the server certificate for the
TLS connection. And AFAIK common practices like cert pinning still have
day 0 gaps. BRSKI effectively provides a method to gain trust into a
server cert without those workarounds. Via the first HTTP transaction.

> I'm not sure that I see the problem here.     

Yes, i think so too, but i like Michael i have FUD about all those possible
changes that are coming via evolution of HTTPS and thay may create
unexpected surprises in the future. So it would certainly helpfull
to get more eyes to check:

    1 -> Initiate HTTPS connection.
    2 -> retrieve cert information of peer from HTTP stack.
         No trust into the cert now but continue.
    3 -> Do one HTTP GET to retrieve voucher artefact
    4 -> Returned voucher allows to cryptographically authenticate
         HTTPS peer certificate. If verification fails, close session
    5 -> Continue to do other HTTP transactions

Any UD (unexpected danger) here with HTTPS evolution or APIs that
try to auto-parallelize ? Or any crazy TLS stuff that would allow
to change certificates used for the connection so that the cert looked
up in 2. would not necessarily be the one used later... ?

If there is any UD, we can still close the HTTPS connection after 4
and create a new one for which we can establish trust in the certificate
during connection setup - and continue with 5. afterwards.

> This is properly RESTful.

Not sure about all RFC7030 transactions done in 5., but should be, yes.

Cheers
    Toerless

---

From: Patrick McManus <[email-masked]>
Date: Wed, 4 Oct 2017 17:03:20 -0400

> server cert without those workarounds. Via the first HTTP transaction.

I'm not totally sure we're speaking the same language but I think you're
misunderstanding the suggestion. Use the trust you establish with your
first transaction to build the cypto-verifiable session key that subsequent
transactions can carry as proof they were serialized (i.e. an application
layer session identifier). It will be much more robust than trying to
figure out what the transport properties of what HTTP treats as independent
transactions are (both in future, and I suspect in some corner cases
present and past).

---

From: Toerless Eckert <[email-masked]>
Date: Thu, 5 Oct 2017 00:22:47 +0200

On Wed, Oct 04, 2017 at 05:03:20PM -0400, Patrick McManus wrote:
> misunderstanding the suggestion.

Which part of cookie did i misunderstand ? ;-P

> Use the trust you establish with your

Lets see first if we can identify actual dangers. If i blindly started to
mistrust any properties of HTTPS, i'd have to start duplicating it. 

Cheers
   Toerless

---

From: Patrick McManus <[email-masked]>
Date: Wed, 4 Oct 2017 19:47:20 -0400

I'm not really looking for a fight - I'm going to focus on the basic
principles and trying to offer advice in good faith.

I'm also not claiming to fully understand brski (is
https://tools.ietf.org/html/draft-ietf-anima-bootstrapping-keyinfra-07
right?).

"

*In BRSKI there are state issues with both the TLS and the HTTP process.
The TLS server certificate is not trusted by the client until after at
least one RESTful interaction occurs.  Only once that has occured is the
connection considered secure. *
is the trust established by the above restful interaction trust in the
certificate (which can be extended to future connections with the same
certificate) or is it trust in the connection that did the exchange? I
presume its the former. If its the connection you have a pretty big problem
because all versions of http allow connections to be torn down at any time,
so you can never rely (in a standards way) of being able to get beyond the
initial exchange.

*We are concerned about how the protocol could become broken if used with
HTTP2 with interleaving of requests/responses."*

how does the protocol deal with issues like parallel connections and
pipelines in h1? Its the same problem.

So rather that trying to restrict the protocol to h1, or to profile h2 down
into a overly complex version of h1, the right answer here is what Michael
suggested (and Martin hinted at) early on - solve it in a state machine
above the http transport level because http as a transport isn't robustly
going to give you ordering (now or in the future) - it inherently thinks of
requests as independent of each other and their connections.

as for concerns about constrained processors, is that something the
protocol should be defining or something that should be configured for the
implementation based on their target platforms (which indeed might be
turned down for low end targets)? It seems you're better off with the
latter approach as HTTP was already designed to negotiate that stuff and
then it can evolve naturally as platforms become more capable.

hth.

---

From: Toerless Eckert <[email-masked]>
Date: Thu, 5 Oct 2017 03:09:29 +0200

> principles and trying to offer advice in good faith.

Definitely, and thank you so much for it! Hope my reply didn't sound
like i wanted to start a cookie fight ;-P.

> https://tools.ietf.org/html/draft-ietf-anima-bootstrapping-keyinfra-07

Yes.

> so you can never rely (in a standards way) of being able to get beyond the

It's the former. First transaction delivers voucher object which establishes
trust into the Cert used by the peer.

> pipelines in h1? Its the same problem.

I think its naturally serialized by the dependencies between the possible
transactions. Eg: building some request requires parts of another transactions
response. And if not that very explicit dependency, then the 
serialization of steps specified in the protocol (such as my step 4.).

> requests as independent of each other and their connections.

Right. I guess i primarily wonder how a programmer using some 
HTTP(S) API could unexpectedly run into reordering issues. Even if i
had a multi-threaded HTTP(S) API with callbacks, it should always be
possible to force serialization. I think, but not sure...

> then it can evolve naturally as platforms become more capable.

I think Michael was brainstorming also from the perspective of a developer
for such low-end platforms. I have not enough understanding of TLS
and HTTP(S) details to make a good judgemenet if low end devices 
would end up having to code & signal more and more unnecessary baggage along the
line of evolution of these protocols - or not.  Assuming of course they
didn't need any new features but just had to follow the evolution anyhow
to not be left behind by bigger peers.

Cheers
    Toerless

---

From: Michael Richardson <[email-masked]>
Date: Thu, 05 Oct 2017 19:42:14 -0400

> This is properly RESTful.

In my opinion EST is not particularly RESTful, it does POSTs which return
bodies, rather than returning a Location: and allowing a cachable GET
afterwards.

    >> and this can break the assumptions of security protocols

When you say "accelerator", do you mean a some kind of TCP proxy for
satellite use?  Or do you mean a load balancer?

The situation where I can envision a problem would be where a client
is written, and it happens to work due to sequencing of HTTP/1.1.
But fails for HTTP2 concurrent operations.

The client is broken, I will not dispute that; part of what I'm asking here
is basically, should there be any considerations written?

The IoT profile for HTTP2 is very interesting because:
  1) it does discuss many of the issues I'm concerned about.
  2) it quite reasonably argues that HTTP2 is sufficiently lighter
     weight thatn 1.1, that devices will appear that do http2,
     and not 1.1.

That profile seems to assume that the constrained device will be the server,
not the client.  I think that's probably realistic for many things.