- From: Ryan Sleevi <sleevi@google.com>
- Date: Mon, 22 Dec 2014 16:09:59 -0800
- To: public-webrtc@w3.org, "public-webcrypto@w3.org" <public-webcrypto@w3.org>
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