Re: WebRTC Certificate Management - a plea to NOT use Web Crypto

As the originator of the idea that Ryan's pleading against, I feel like I
should provide some response here.  In the spirit of long messages for the
holidays, ...

First, Ryan, thanks for taking the time to lay out the overall context.
Your characterization of the high-level requirements and the arguments for
reusing CryptoKey are pretty much accurate.  Though I reserve the right to
disagree with them on some points :)

If I were to summarize your proposal for WebRTC in a sentence, it would be,
"Create a custom key pair object that is specific to WebRTC".  If you look
at this just in the context of WebRTC, that doesn't sound all that bad.
However,
I'm concerned about the bigger direction for APIs.

I want to live in a world where cryptographic security is easy and
ubiquitous.  WebRTC and WebPush are both good examples of new APIs that
build security in from the start, and indeed make it a core component.  I
want it to be easy for future APIs to do that too.

Forcing each API to make a new "LimitedUseKey" construct is inimical to
that objective.  Different APIs have different event structures, but we
don't make developers learn a new event system for each API -- we map the
API to DOM Events or Promises.  So whatever we end up with, it should be
re-usable across at least WebRTC and WebPush, and hopefully future things
as well.  In other words, the choices here are one key object or two --
CryptoKey or CryptoKey+ApplicationUsableKey -- not O(#apis) different
versions.

The main question, then, is how big the difference is between CryptoKey and
ApplicationUsableKey.  The base requirements we're seeing are for public
and private key objects with the following properties (to refine your
requirements list a bit, with a separate numbering space):

[Requirement A=1,2] Private keys are protected from application access
(browser-locked)
[Requirement B=3] Private keys can be scoped to specific uses
[Requirement C=4] Private keys can be persisted
[Requirement D=5] Public keys can be serialized to different formats

CryptoKey provides these properties.  Any ApplicationUsableKey construct
would have to duplicate at least that much of CryptoKey.  This gets us down
to the question of what harm there would be in re-using CryptoKey.

It seems like there are a couple of things that are making you sad about
the idea of re-using CryptoKeys for applications outside of WebCrypto.

[Objection 1] If other apps use CryptoKeys, they won't be usable with
WebCrypto methods.
[Objection 2] WebCrypto's algorithms align poorly with TLS

Both of these arguments seem to miss the fact that WebCrypto itself is an
application of CryptoKeys.  It's the first, and one that was co-designed
with CryptoKeys, but it need not be the only.  In fact, it's a *set* of
applications -- sign, verify, encrypt, and decrypt.  Each of these has
separate processing for keys.  In light of that, Objection 1 looks kind of
funny: We *already* have WebCrypto keys that are usable for one application
and not another, e.g., sign() and not decrypt().  It's baked into the
design.

Objection 2 misses another important underlying fact: While CryptoKey
expresses constraints, it's up to the application to enforce that
constraint in a manner appropriate to that application.  Each of the
WebCrypto algorithm descriptions describes different processing for the
"algorithm" dictionary on the key.  A TLS usage could do likewise, e.g.,
ignoring the "hash" parameter on an RSASSA-PKCS1-v1_5 algorithm if present.

It may be that the requirements from other applications lead to some
changes to the CryptoKey structure, e.g., to make the "hash" parameter not
required by the syntax (it can still be enforced by sign()).  I'm OK with
that.  It's not monkey-patching, it's discovering weaknesses in CryptoKey
that prevent it from being reusable.  And it's a natural, healthy process
for APIs to go through.

Happy holidays,
--Richard















On Mon, Dec 22, 2014 at 7:09 PM, Ryan Sleevi <sleevi@google.com> wrote:
>
> 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 14:21:54 UTC