Subject: Re: [Webpush] Major change to encryption

From: Costin Manolache <[email-masked]>
Date: Tue, 01 Nov 2016 17:58:14 +0000

Using the Crypto-Key for vapid is fine with me - I have no problem with
keeping it for this purpose, in vapid spec. Or to use Crypto-Key in
other specs that deal with key distribution or other things.

However I still think that for consistency, the dh-public key used for
decrypting
the message should be in the binary header, next to salt - maybe even
 using the 'key id' field ( renamed to 'symmetric key id or public key' ).
The binary blob should be sufficient to decode the message, if the
content-encoding is known, using secrets known to the receiver ( symmetric
key in http case, or EC private key for webpush ).

I think it's important to recognize that client-to-pushservice communication
may use different transports, in addition to http/2 push promises. In
particular
it may be layered over Webcoket, newly proposed WiSH, etc - and in many
cases the implementation will be greatly simplified if the binary blob can
be sent as-is (after any protocol-specific authentication ).

Costin

On Mon, Oct 31, 2016 at 4:57 PM Martin Thomson <[email-masked]>
wrote:

Hi Peter and JR,

Thanks both for picking up on my stupid errors.  Hasty is not always
careful enough, but I was working to a time limit.  With 5 minutes
left, I think that I managed to get all your input integrated.

And your reminder about vapid was timely.  I think that we can
dispense with any attempt to remove Crypto-Key, since we have to have
it for vapid anyway.

Now I need to think about getting the python implementation updated.

--Martin

On 1 November 2016 at 10:31, Peter Beverloo <[email-masked]> wrote:
> Hi Martin,
>
> Thanks for the update and the proposal!
>
> I've reviewed these today, and have minor some points of feedback. I'll
> deliberately avoid the topics of interoperability and upgrade cost here.
>
> First of all, this indeed vastly improves layering between the drafts. I
> very much like how webpush-encryption is now built on top of encryption-
> encoding as opposed to being some sort of fork.
>
>>> A push message MUST include a zero length keyid parameter in the
>>> content coding header. This allows implementations to ignore the first
>>> 21 octets of a push message.
>
> I don't think this is right. The `salt` and the `rs` must still be known,
> and those are included in the header.
>
>>> A push service is not required to support more than 4096 octets of
>>> payload body (see Section 7.2 of [I-D.ietf-webpush-protocol]), which
>>> equates to at most 4059 octets of cleartext.
>
> I think this forgot about the padding --
>
>   4096 - 16 (auth) - 2 (padding length) - 21 (header w/o keyid) = 4,057
>
> May also want to s/cleartext/plaintext/ for consistency with encryption-
> encoding.
>
>>> An Application Server MUST include exactly one aes128gcm content
>>> coding, and at most one entry in the Crypto-Key field. This allows the
>>> keyid parameter to be omitted.
>
> This means the draft is incompatible with VAPID again. It must have at
> most one Crypto-Key entry that has a `dh` value.
>
> I haven't yet been able to validate the examples in the draft, but it
> sounds like you're changing these anyway per jr's feedback (+1 to that).
>
> Thanks,
> Peter
>
>
> On Mon, Oct 31, 2016 at 11:19 PM, Martin Thomson <[email-masked]
>
> wrote:
>>
>> On 1 November 2016 at 10:07, jr conlin <[email-masked]> wrote:
>> > One small comment, then? Can we change the transmitted Content-Encoding
>> > type to match the new Content-type of "aes128gcm" instead of the long
>> > abandoned "aesgcm128"? (See point #4)
>>
>> Ouch, that's going to hurt.  I'll have to redo the examples :*(  40
>> minutes until the deadline, go!
>>
>> _______________________________________________
>> Webpush mailing list
>> [email-masked]
>> https://www.ietf.org/mailman/listinfo/webpush
>
>

_______________________________________________
Webpush mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/webpush

---

From: Costin Manolache <[email-masked]>
Date: Tue, 01 Nov 2016 18:02:52 +0000

I would also add that some of the bugs we've seen in our implementation
were related to parsing and passing along the crypto key. Even for
VAPID I would love to see the sender public key appended to the
Authorization header somehow instead of in a separate Crypto-Key header.

Costin

On Tue, Nov 1, 2016 at 10:58 AM Costin Manolache <[email-masked]> wrote:

> > On Mon, Oct 31, 2016 at 11:19 PM, Martin Thomson <
> [email-masked]>
> > wrote:
> >>

---

From: jr conlin <[email-masked]>
Date: Tue, 1 Nov 2016 12:46:21 -0700

I'll agree that putting as much crypto in the message would be great.
One thing to note is that when messages are delivered over bridged
connections (like GCM/FCM or APNs) all that added content eats into the
preciously small available delivery content. Particularly when you have
to encode to base64 for JSON envelopes.

We should strive to have as little required "prefix" content as
possible, else folks wind up only able to send a few hundred bytes across.

On 11/1/2016 10:58 AM, Costin Manolache wrote:
> On Mon, Oct 31, 2016 at 4:57 PM Martin Thomson
> <[email-masked] <mailto:[email-masked]>> wrote:
>
>     Hi Peter and JR,
>
>     On 1 November 2016 at 10:31, Peter Beverloo <[email-masked]
>     <mailto:[email-masked]>> wrote:
>     > Hi Martin,
>     >
>     > On Mon, Oct 31, 2016 at 11:19 PM, Martin Thomson
>     <[email-masked] <mailto:[email-masked]>>
>     > wrote:
>     >>
>     >> On 1 November 2016 at 10:07, jr conlin <[email-masked]
>     <mailto:[email-masked]>> wrote:
>     >> [email-masked] <mailto:[email-masked]>
>     [email-masked] <mailto:[email-masked]>

---

From: Costin Manolache <[email-masked]>
Date: Wed, 02 Nov 2016 01:00:54 +0000

Yes, when sending over GCM it's better to have the 65bytes of the key in
the binary prefix of the
"raw_data" byte[] instead of having to add another key/value pair, with the
b64 encoding and proto
overhead. But it's an optimization - not the main reason :-). A nice extra
benefit is that browsers on android
could dispatch the message based on the raw_data only, since the EC public
key can identify the app/SW.

Costin

On Tue, Nov 1, 2016 at 12:46 PM jr conlin <[email-masked]> wrote:

> I'll agree that putting as much crypto in the message would be great. One
> thing to note is that when messages are delivered over bridged connections
> (like GCM/FCM or APNs) all that added content eats into the preciously
> small available delivery content. Particularly when you have to encode to
> base64 for JSON envelopes.
>
> We should strive to have as little required "prefix" content as possible,
> else folks wind up only able to send a few hundred bytes across.
>
>

---

From: Martin Thomson <[email-masked]>
Date: Wed, 2 Nov 2016 14:50:09 +1100

On 2 November 2016 at 12:00, Costin Manolache <[email-masked]> wrote:
> Yes, when sending over GCM it's better to have the 65bytes of the key in the
> binary prefix of the

As I said, I'm not opposed to this, it just seems wrong.

Moving the public key into the body will cut into message budgets.
We'll be at 3994 octets of plaintext maximum if we do that.  One of
the nice things with the header field is that users don't pay for it.
The bad thing is that the server needs to find a way to move it.

If we are going to make this change, we need to be very crisp about it.

---

From: JR Conlin <[email-masked]>
Date: Tue, 1 Nov 2016 21:02:17 -0700

​On Tue, Nov 1, 2016 at 8:50 PM, Martin Thomson <[email-masked]>
wrote:

> We'll be at 3994 octets of plaintext maximum if we do that.
>
​​

​I'm a bit confused about that. For "native" networks, push servers have
pretty wide tolerances for how much data that they can send over their
pipes. Going between services, I can definitely understand, since you're
held to the limits of the provider system. (APNs limits to about 2K, so
users are kinda screwed worse.) Of course, with "bridged" systems like
those, you still have to deal with the host system, so "headers" aren't
free. You still have to encode the data into the body of the message in
some fashion, which eats into the available amount.

Worst of all, is that those bridged systems are also unreliable for hosts
of reasons and then you're re-implementing TCP with one hand tied behind
your back.​

Granted, I've got a pretty limited viewpoint, so I'm sure I'm missing
something obvious.

On Tue, Nov 1, 2016 at 8:50 PM, Martin Thomson <[email-masked]>
wrote:

> the

---

From: Martin Thomson <[email-masked]>
Date: Wed, 2 Nov 2016 15:25:42 +1100

On 2 November 2016 at 15:02, JR Conlin <[email-masked]> wrote:
> I'm a bit confused about that. For "native" networks, push servers have
> free. You still have to encode the data into the body of the message in some
> fashion, which eats into the available amount.
>
> Worst of all, is that those bridged systems are also unreliable for hosts of
> reasons and then you're re-implementing TCP with one hand tied behind your
> back.
>

If you intend to implement this over APNS, then you are stuck, I
agree.  Unless you fragment (and reassembly is ugly).

In the end, the point is to create a consistent experience for users
of the API, we need to pick a point that works.  Currently, the keys
go into the "overhead" bucket: stuff that the push service has to wear
above the 4k message size.  Moving the key into the message is just
moving things around, but it does mean that users of the API get even
less space to play with than before.

I guess you could say that we're stealing 21 octets already, why not make it 85?

---

From: Costin Manolache <[email-masked]>
Date: Wed, 02 Nov 2016 04:43:25 +0000

AFAIK the "DH" public key must be sent to the device no matter what.

Right now for GCM, if you use the webpush endpoint the headers end up in
the key/value pairs, as base64, while the binary data goes in the raw_data.
I have no problem if the spec defines that the binary header should be
excluded - and
 push services support 4k of real data ( i.e. continue to exclude the
header overhead).

If transmitting over other transports - somehow we need to send the dh
public key and
the body - if it doesn't fit a tickle+poll or segmentation need to be used.
The fact the
 public key was received in a header or was part of the body doesn't change
this.

Costin

---

From: Costin Manolache <[email-masked]>
Date: Wed, 02 Nov 2016 04:46:47 +0000

I now understand your concern - no need to steal any octet, just define
that
real message size should be 4k. I believe aesgcm also adds few byes for
authentication - we can define that the cleartext can be 4k, with header
and crypto overhead excluded..

Costin

On Tue, Nov 1, 2016 at 9:43 PM Costin Manolache <[email-masked]> wrote:

> the body - if it doesn't fit a tickle+poll or segmentation need to be
> used. The fact the
>  public key was received in a header or was part of the body doesn't
> change this.
>
> Costin
>

---

From: Martin Thomson <[email-masked]>
Date: Fri, 4 Nov 2016 11:27:49 +1100

On 2 November 2016 at 15:46, Costin Manolache <[email-masked]> wrote:
> I now understand your concern - no need to steal any octet, just define that

I haven't increased the size limit, but I have made the request
change.  See what you think:

https://github.com/webpush-wg/webpush-encryption/pull/9

I've updated my node.js implementation to match (that's how I
generated the example):

https://github.com/martinthomson/encrypted-content-encoding/pull/28

(I'm working on an update to -vapid as we speak.)