- From: Ryan Sleevi <sleevi@google.com>
- Date: Mon, 27 Aug 2012 17:50:19 -0700
- To: Arun Ranganathan <arun@mozilla.com>
- Cc: Vijay Bharadwaj <Vijay.Bharadwaj@microsoft.com>, Arun Ranganathan <aranganathan@mozilla.com>, "public-webcrypto@w3.org" <public-webcrypto@w3.org>, GALINDO Virginie <Virginie.GALINDO@gemalto.com>, Wan-Teh Chang <wtc@google.com>, David Dahl <ddahl@mozilla.com>, Wendy Seltzer <wseltzer@w3.org>, Harry Halpin <hhalpin@w3.org>
On Wed, Aug 22, 2012 at 2:33 PM, Arun Ranganathan <arun@mozilla.com> wrote: > On Aug 17, 2012, at 5:48 PM, Ryan Sleevi wrote: > >> On Tue, Aug 14, 2012 at 9:32 AM, Vijay Bharadwaj >> <Vijay.Bharadwaj@microsoft.com> wrote: >>> I agree with Arun that we should support key neutering of some sort. >>> >>> Keys are in fact significantly expensive objects to set up. For example, keys in secure elements need a construct to convey PIN caching lifetime, while AES and HMAC keys require fairly expensive key expansion to be done up front. So it is useful to have a Key object that can last across operations for an application-controlled amount of time. This seems to necessitate a destroy or neuter operation for keys. >> >> Sure, but isn't this already handled by the existing JS GC semantics? >> >> The "set-up" argument seems like one that argues in favour of >> reference cloning, but that should already be possible: >> var key1 = /* get some key */; >> var key2 = key1; /* key2 is now a reference/clone of key1 */ >> >> My understanding was that Blob neutering was a way of addressing Blobs >> that were Transferrable. Because Worker memory allocation is different >> than the JS "main thread", there needed to be a way to safely pass >> memory "ownership" over to the Worker - hence, Transferrable. >> >> It seems like the arguments being made here are to have some form of >> "destructor", which seems counter-intuitive towards the design of JS >> as a language. If we're concerned that JS will leak the objects, >> rather than GC, what guarantees do we have that app developers will >> remember to explicitly dispose their keys? > > > Quick point of clarification: Blobs can be neutered, but cannot be transferred (since "transferring" in the context of "Transferable" makes no sense for Blob objects). In other words, Blob does not implement Transferable. Which of course does beg the question about *why* Blobs can be neutered with a .close() operation in the first place. > > The answer is in fact to allow better memory management, and not to rely on GC! [GCvsExpensiveResources]. Blobs are not transferable precisely because they are immutable, and because we can implement using postMessage on Blob objects without "transferring" them. > > But note that they *do* refer to potentially arbitrarily large amounts of data. It seemed prudent to supplement GC'ing Blobs with an explicit close() that actually says nothing about GC behavior, but does neuter a Blob making subsequent read access a no op. A bug logged on me to actually make Blob Transferable has been marked WONTFIX by Jonas Sicking [NOTransferable]; close() is deemed sufficient, with anything else deemed 'syntactic sugar.' > > The impact this discussion of Blob has on Key objects is debatable, because you could say that Key sizes are constrained in memory (it's possible to conceive an upper bound on these), whereas it is actually *key generation* which could be expensive. It's hard for me to conceive of a crypto application that uses an arbitrary number of *separate* Key objects and keeps them around for a while. > > The case for neutering keys might be a security consideration; that is, a Key object, depending on what it represents, might be sensitive. And neutering it clips the wings of bad things that can be done with it. In general, in an earlier message you say that implementations should test whether to make Key objects neuter-able, and determine what the memory considerations are. The security considerations are also open here, so that could be how we resolve this discussion. > > In general, operations like close() are for savvy web developers. We've tested the myth of omniscient GC, just as endianness considerations in ArrayBuffer test the myth of total (underlying) platform independence. > > -- A* > > [GCvsExpensiveResources] https://www.w3.org/Bugs/Public/show_bug.cgi?id=16952#c2 > [NOTransferable] https://www.w3.org/Bugs/Public/show_bug.cgi?id=18611 > > Thanks for this pointers. Perhaps incorrectly, but I've been conceiving as Key objects as similar to object URIs. There are not the data in and of themselves, merely a promise to provide that data when needed (eg: for a Crypto Operation). A Key object does not necessarily represent a handle to an underlying data store - I'm not sure that any object COULD reasonably guarantee such a behaviour, given the wide variance of APIs, smart cards, and secure element semantics regarding how many parallel keys they can have open at a time. The closest the semantics of close seem to be akin to revokeObjectURL. However, I'm nervous comparing it to even that, since naturally one thinks of autoRevoke = true as part of the objectURLOptions, whereas I'm not sure if the same makes sense for Key objects. In particular, consider accessing common keys (whether window.crypto.keys or via some query mechanism). Unless there was a way to say "Don't auto-revoke THESE keys", you'd only be able to use them for a single operation, before you need to re-query/re-get the Key handle. Surely, that seems inefficient/wrong. For persistent keys, the equivalent to revokeObjectURL would be the KeyStorage.removeKey method. It seems like that could/should be normatively spec'd to invalidate any references to that key (including any in-progress operations), trigger the CryptoOperations onerror handling, etc. For ephemeral keys, dropping the object should be sufficient - especially since the ephemeral keys don't live in window.crypto.keys (which only contains 'persistent' keys) As far as "spec smells" go, how does the above proposal smell to you, Arun?
Received on Tuesday, 28 August 2012 00:50:47 UTC