Draft: draft-ietf-webpush-encryption

Commentary: In httpwg / http - extensions I have proposed the removal of the Diffie - Hellman pieces . This PR adopts the parts that were removed from the base spec that webpush needs . In the process , I 've had to make a bunch of changes . It loses a bit of generality , which makes things easier to follow , which I 've tried to capitalize on by being a lot more explicit about the overall process . . would you mind reviewing this change to see that I have n't messed something up ?
For each new subscription that the User Agent generates for an
application, it also generates an asymmetric key pair for use in
Diffie-Hellman (DH) DH or elliptic-curve Diffie-Hellman (ECDH) ECDH.
The public key for this key pair can then be distributed by the
application to the Application Server along with the URI of the
subscription.  The private key MUST remain secret.
This key pair is used with the Diffie-Hellman key exchange as
described in Section 4.2 of I-D.ietf-httpbis-encryption-encoding.
A User Agent MUST generate and provide a public key for the scheme
described in mti.
The public key MUST be accompanied by a key identifier that can be
used in the "keyid" parameter to identify which key is in use.  Key
identifiers need only be unique within the context of a subscription.
As described in I-D.ietf-httpbis-encryption-encoding, use of Diffie-
Hellman for key agreement requires that the receiver provide clear
information about its chosen group and the format for the "dh"
parameter with each potential sender.
This document only describes a single ECDH group and point format,
described in mti.  A specification that defines alternative groups or
formats MUST provide a means of indicating precisely which group and
format is in use for every public key that is provided.
The application using the subscription distributes the key identifier
and public key along with other subscription information, such as the
subscription URI and expiration time.
The communication medium by which an application distributes the key
identifier and public key MUST be confidentiality protected for the
reasons described in I-D.ietf-webpush-protocol.  Most applications
that use push messaging have a pre-existing relationship with an
Application Server.  Any existing communication mechanism that is
authenticated and provides confidentiality and integrity, such as
HTTPS RFC2818, is sufficient.
The authentication secret ensures that exposure or leakage of the DH
public key - which, as a public key, is not necessarily treated as a
secret - does not enable an adversary to generate valid push
messages.
A User Agent MUST generate and provide a hard to guess sequence of
octets that is used for authentication of push messages.  This SHOULD
be generated by a cryptographically strong random number generator
RFC4086 and be at least 16 octets long.
An Application Server that has the public key, group and format
information plus the authentication secret can encrypt a message for
the User Agent.
The Application Server generates a new DH or ECDH key pair in the
same group as the value generated by the User Agent.
From the newly generated key pair, the Application Server performs a
DH or ECDH computation with the public key provided by the User Agent
to find the input keying material for key derivation.  The
Application Server then generates 16 octets of salt that is unique to
the message.  A random RFC4086 salt is acceptable.
Web push uses the authentication secret defined in Section 4.3 of I-
D.ietf-httpbis-encryption-encoding.  This authentication secret (see
auth) is generated by the user agent and shared with the application
server.
the public key for its DH or ECDH key pair is placed in the "dh"
parameter of the Crypto-Key header field.
Note that a push service is not required to support more than 4096
octets of payload body, which equates to 4077 octets of cleartext, so
the "rs" parameter can be omitted for messages that fit within this
limit.
An application server MUST NOT use other content encodings for push
messages.  In particular, content encodings that compress could
result in leaking of push message contents.  The Content-Encoding
header field therefore has exactly one value, which is "aesgcm128".
Multiple "aesgcm128" values are not permitted.
An application server MUST NOT include an "aesgcm128" parameter in
the Encryption header field.
A User Agent decrypts messages are decrypted as described in I-
D.ietf-httpbis-encryption-encoding.  The authentication secret
described in derivation is used in key derivation.
Note that the value of the "keyid" parameter is used to identify the
correct share, if there are multiple values for the Crypto-Key header
field.
A receiver is not required to support multiple records.  Such a
receiver MUST check that the record size is large enough to contain
the entire payload body in a single record.  The "rs" parameter MUST
NOT be exactly equal to the length of the payload body minus the
length of the authentication tag (16 octets); that length indicates
that the message has been truncated.
This document has no IANA actions.
Encrypting a push message uses elliptic-curve Diffie-Hellman (ECDH)
ECDH on the P-256 curve FIPS186 to establish a shared secret (see dh)
and a symmetric secret for authentication (see auth).
A User Agent generates an ECDH key pair and authentication secret
that it associates with each subscription it creates.  The ECDH
public key and the authentication secret are sent to the Application
Server with other details of the push subscription.
When sending a message, an Application Server generates an ECDH key
pair and a random salt.  The ECDH public key is encoded into the "dh"
parameter of the Crypto-Key header field; the salt is encoded into
the "salt" parameter of the Encryption header field.  The ECDH key
pair can be discarded after encrypting the message.
The content of the push message is encrypted or decrypted using a
content encryption key and nonce that is derived using all of these
inputs and the process described in encryption.
The application using the subscription distributes the subscription
public key and authentication secret to an authorized Application
Server.  This could be sent along with other subscription information
that is provided by the User Agent, such as the push subscription
URI.
An application MUST use an authenticated, confidentiality protected
communications medium for this purpose.  In addition to the reasons
described in I-D.ietf-webpush-protocol, this ensures that the
authentication secret is not revealed to unauthorized entities, which
can be used to generate push messages that will be accepted by the
User Agent.
Most applications that use push messaging have a pre-existing
relationship with an Application Server.  Any existing communication
mechanism that is authenticated and provides confidentiality and
integrity, such as HTTPS RFC2818, is sufficient.
The input keying material used for deriving the content encryption
keys used for the push message is derived using elliptic-curve
Diffie-Hellman ECDH (dh).
This is then combined with the application secret to produce the
input keying material used in I-D.ietf-httpbis-encryption-encoding
(combine).
A content encryption key and nonce are derived using the process
in I-D.ietf-httpbis-encryption-encoding with an expanded context
string (context).
Encryption or decryption follows according to I-D.ietf-httpbis-
encryption-encoding.
The key derivation process is summarized in summary.  Restrictions on
the use of the encrypted content coding are described in restrict.
For each new subscription that the User Agent generates for an
Application, it also generates a P-256 FIPS186 key pair for use in
elliptic-curve Diffie-Hellman (ECDH) ECDH.
When sending a push message, the Application Server also generates a
new ECDH key pair on the same P-256 curve.
The ECDH public key for the Application Server is included in the
"dh" parameter of the Crypto-Key header field (see iana).  The
uncompressed point form defined in X9.62 (that is, a 65 octet
sequence that starts with a 0x04 octet) is encoded using base64url
RFC7515 to produce the "dh" parameter value.
An Application combines its ECDH private key with the public key
provided by the User Agent using the process described in ECDH; on
receipt of the push message, a User Agent combines its private key
with the public key provided by the Application Server in the "dh"
parameter in the same way.  These operations produce the same value
for the ECDH shared secret.
A User Agent MUST generate and provide a hard to guess sequence of 16
octets that is used for authentication of push messages.  This SHOULD
be generated by a cryptographically strong random number generator
RFC4086.
The shared secret produced by ECDH is combined with the
authentication secret using HMAC-based key derivation function (HKDF)
described in RFC5869.  This produces the input keying material used
by I-D.ietf-httpbis-encryption-encoding.
The derivation of the content encryption key and nonce uses an
additional context string.
The context is comprised of a label of "P-256" encoded in ASCII (that
is, the octet sequence 0x50, 0x2d, 0x32, 0x35, 0x36), a zero-valued
octet, the length of the User Agent public key (65 octets) encoded as
a two octet unsigned integer in network byte order, the User Agent
public key, the length of the Application Server public key (65
octets), and the Application Server public key.
Note that this omits the exclusive OR of the final nonce with the
record sequence number, since push messages contain only a single
record (see restrict) and the sequence number of the first record is
zero.
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 4077 octets of cleartext, so the "rs" parameter can be
omitted for messages that fit within this limit.
An Application Server MUST NOT use other content encodings for push
messages.  In particular, content encodings that compress could
result in leaking of push message contents.  The Content-Encoding
header field therefore has exactly one value, which is "aesgcm".
Multiple "aesgcm" values are not permitted.
An Application Server MUST NOT include an "aesgcm" parameter in the
Encryption header field.
A User Agent is not required to support multiple records.  A User
Agent MAY ignore the "rs" parameter.  If a record size is size is
present, but unchecked, decryption will fail with high probability
for all valid cases.  Decryption will also succeed if the push
message contains a single record from a longer truncated message.
Given that an Application Server is prohibited from generating such a
message, this is not considered a serious risk.
The following example shows a push message being sent to a push
service.
This example shows the ASCII encoded string, "I am the walrus".  The
content body is shown here encoded in URL-safe base64url for
presentation reasons only.  Line wrapping of the "dh" parameter is
added for presentation purposes.
Since there is no ambiguity about which keys are being used, the
"keyid" parameter is omitted from both the Encryption and Crypto-Key
header fields.  The keys shown below use uncompressed points X9.62
encoded using base64url.
The sender's private key used in this example is "nCScek-QpEjmOOlT-
rQ38nZzvdPlqa00Zy0i6m2OJvY".  Intermediate values for this example
are included in ex-intermediate.
This document defines the "dh" parameter for the Crypto-Key header
field in the "Hypertext Transfer Protocol (HTTP) Crypto-Key
Parameters" registry defined in I-D.ietf-httpbis-encryption-encoding.
Purpose: The "dh" parameter contains a Diffie-Hellman share which
is used to derive the input keying material used in "aesgcm"
content coding.
Reference: this document.