WebRTC Certificate Management - a plea to NOT use Web Crypto

I've been informed that as a result of the TPAC 2014 WebRTC discussion
[1], there's a proposal [2] to use WebCrypto [2] to generate and store
keys used by peer connection. I originally left my comments on [3],
because the WebRTC workmode was unclear/underdocumented, but I've been
requested by the chairs to echo these to the list.

Apologies for the length of this message - hopefully the holiday break
will provide sufficient time to read and digest these concerns. I wish
there was something shorter I could reply to, but I first need to
spell out my understanding of the situation so that my arguments
against make sense.

I've previously discussed this proposal with Richard Barnes and Justin
Uberti, and had hoped that the many concerns raised would have seen
this line of thinking avoided, because I think it's dangerous for both
APIs.

At the risk of presenting a set of strawman arguments, from the past
minutes, list archives, and other pull requests, I'm unable to find
any set of consistent documentation about the expectation of keys for
WebRTC or of the arguments for why Web Crypto meets them. I'm forced
to draw upon the justifications provided privately by the proponents
in the past, but apologies if these are incomplete, misrepresentative,
or have since changed; hopefully this discussion will at least spark
the group to document these.

I've heard a set of requirements laid out for WebRTC keys, which I'll
try to recount here:

[Requirement 1] WebRTC keys must be 'browser locked' - that is, they
must be created explicitly by the UA and never be imported/importable
(e.g. via crypto.subtle.importKey [5] )
[Requirement 2] WebRTC keys must not be extractable
[Requirement 3] WebRTC keys must not be used for any other purpose
other than WebRTC
[Requirement 4] WebRTC keys must have some form of stable storage
(IndexedDB or other)
[Requirement 5] WebRTC must expose the public keying material in some
form to applications (in order to allow identity management)
[Requirement 6-ish] There are some who would like to see
pre-provisioned WebRTC keys exposed (e.g. provisioned by the UA as
part of a sign-in process, provisioned in hardware, etc)

I've also heard a set of arguments for why Web Crypto is a good or logical fit:

[Argument 1] WebRTC uses cryptography, Web Crypto uses cryptography,
therefore there's overlap.
[Argument 2] WebRTC needs opaque storage of keys, Web Crypto provides
opaque storage of keys, therefore there's overlap.
[Argument 3] WebRTC needs a language to be able to express how to
generate keys, Web Crypto provides a language (vis-a-vis [4]),
therefore, there's overlap.
[Argument 4] Web Crypto defines a "structured clone" language, and
it'd be a shame to duplicate that for Web RTC


Argument 1 is, in my opinion, a poor justification. WebRTC's use of
crypto is ostensibly high level, whereas Web Crypto is very much a
low-level API. The crypto employed is at very different levels for the
script author to influence and control. I haven't seen any proposals
for allowing the script author to control DTLS ciphersuites, for
example, and I'd be similarly opposed if there was such a proposal.

Argument 2 is trivial - defining structured clone for a new type is
well defined and extensible [6]. Arguments to use the same type, as a
means of saving implementation complexity, only hold water if it
results in something easier for web developers. That is, if the
redundant use of the type introduces new complexities - and in this
case, I believe it does - then in the priority of constituencies [7],
we should favour them over implementors.

Argument 3 is where cracks truly begin to form. The pull request
proposes allowing four algorithms - RSAES-PKCS1_v1_5, RSASA-PKCS1_v1_5
(a typo, it should be RSASSA-PKCS1-v1_5), RSA-PSS, and ECDSA. These
are meant to parallel their use within DTLS (as used by WebRTC). There
are, however, several glaring issues with this:
- RSA-ES (as used by a DTLS client and server for the Premaster Secret
exchange) has been explicitly removed from Web Crypto due to its
dangers (arguably everywhere "but" TLS/DTLS, but as we've seen in the
past few years, even the TLS stacks are left vulnerable)
- RSA-SSA (as used by DTLS as part of a CertificateVerify) is
restricted by WebCrypto to only being usable with a particular hash
algorithm, which limits the negotiating ability of the client and
server on choosing acceptable security strength. If following Web
Crypto's security considerations, then this key MUST NOT be usable for
TLS servers that aren't doing ephemeral-DH exchanges as well.
- RSA-PSS is noted for "future compatibility", except no such
specification requires it, and the proposal leaves it entirely
underspecified as to how this is to be used within a DTLS exchange.
- If accepting the logic for PSS, then RSA-OAEP should also be
included - except it also has the same 'issues' as the RSA family
algorithms

Of these algorithms, only ECDSA has any relevance/semblance of
commonality to the TLS usage of this.

Argument 4 is really a restatement of Argument 2, and is an
implementor-only concern. That is, there's nothing preventing
implementations from implementing Web Crypto and WebRTC in terms of
the same libraries (and I suspect they will), but such a decision can
be transparent to the script author.

My biggest concern is that the CryptoKeys proposed to be generated are
unusable with any aspect of the Web Crypto API, save for exportKey.
This is absolutely silly nonsense that will frustrate developers to no
end, and on both sides. It effectively monkey-patches the WebCrypto
spec to add new usages, when it's known that WebCrypto isn't too keen
on this.

I'd like to propose a (hopefully) simpler alternative:

RTCKeys.generateKey takes a WebRTC-specific algorithm that is, for the
current key types, expressed simply as 'RSA'+key strength or
'ECDSA'+curve. RSA parameters for modulus length (implementation
defined, although I hope every implementation will sensibly choose F4)
and hash binding (unnecessary in the TLS case, because it won't be
attacker-misused) are omitted. Or perhaps don't even allow the caller
to specify - let the UA decide (perhaps all it supports) and allow
DTLS negotiation to handle selecting the appropriate strength that the
UA is willing to negotiate, transparent to the script author.

Return a WebRTC key object. This key object can expose the public key
in whatever representation you want, but I'd suggest simply an
'object' attribute type whose value is the result of exporting the
public key to JWK and encoded as a JS object. The WebRTC key object is
structured clonable - preserving the opacity requirement and offering
long-term storage capabilities. You can decide whether or not
Requirement 6 is real, and if so, do so independently of WebCrypto.
You can define appropriate key policies over time (e.g. disallowing
RSA 1024-bit certs or SHA-1 signatures in WebRTC, as I hope you will),
you can attach whatever metadata you need, all independently.

In short, return an object that fits your API model and is usable with
your API, and neither impinges or misaligns with other APIs. Further,
the approach proposed by Web RTC  is being proposed for other APIs
[8], where such an approach would be even more of a mismatch for
developers and a security issue for implementors.


[1] http://www.w3.org/2014/10/30-webrtc-minutes.html#item04
[2] https://github.com/w3c/webrtc-pc/pull/28
[3] https://github.com/w3c/webrtc-pc/pull/28#issuecomment-65422143
[4] https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#algorithm-dictionary
[5] https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-importKey
[6] https://html.spec.whatwg.org/multipage/infrastructure.html#safe-passing-of-structured-data
[7] http://www.w3.org/TR/html-design-principles/#priority-of-constituencies
[8] https://github.com/w3c/push-api/issues/55

Received on Tuesday, 23 December 2014 00:11:03 UTC