- From: <bugzilla@jessica.w3.org>
- Date: Tue, 17 Jun 2014 21:39:57 +0000
- To: public-script-coord@w3.org
https://www.w3.org/Bugs/Public/show_bug.cgi?id=23369 --- Comment #22 from Ryan Sleevi <sleevi@google.com> --- (In reply to Allen Wirfs-Brock from comment #21) > For example, in the WebCrypot API I notice that the encrypt and decrypt > methods both are specified to clone their data parameters. Why? It certainly > doesn't make any sense to modify the data buffer after the initial call and > before processing starts, but is there any integrity or other essential > reasons that must be actively guarded against with the cost of forcing a > copy of a potentially large buffer? Since this is core to the discussion on this bug, I'll address it. There are several questions that are more specific to WebCrypto that, for sake of those following this bug, I've not answered. I'm more than happy to follow-up on public-webcrypto@ if you want to continue the discussion/API concerns there. As it relates to this, the Promise vended by these operations (and it's not just encrypt/decrypt but *all* of the SubtleCrypto operations, save for exportKey), the user agent continues asynchronously processing the data 'in the background'. As such, we need to ensure that the user does not mutate data at the same time the implementation is reading data, and that implementations afford consistency to script authors. There is not, within Promise-using ES6, seemingly any requirement for synchronizing access to data to the task queue; indeed, that could be quite bad for some cases (example being networking events). Cryptographic operations can be costly, not just in CPU terms, but in some implementations, may result in IO waits. Many cryptographic APIs are blocking APIs themselves. Even a small buffer (of 20 bytes) can, for some operations, cause multi-second stalls if backed by hardware. This API was designed to support both hardware and software-backed operations, even if we expect most of the first implementations are software-backed (as that's what the spec currently favours in description). Because of the hardware requirements, we don't want to pause the ES microtask pool / HTML task pool in order to synchronously invoke these methods; we would instead prefer to treat them like networking events (eg: dispatch data to some API, receive asynchronous notification of completion). The output of the cryptographic operation should be consistent with its inputs. If we allowed arbitrary modification, we can run into situations like: var a = new Uint8Array(4); a.set([0, 1, 2, 3]); var promise = crypto.subtle.encrypt(.., a, ...); // At this time slice, the UA has not yet begun the encryption operation, // because the underlying subsystem may only support a single pending operation, // and the encrypt() is still pending a[0] = 4 promise.then(result => { // Does result contain ciphertext for [0, 1, 2, 3] or for [4, 1, 2, 3] }); This is why an explicit copy is noted; the actual transformation of the input, plaintext buffer (A) is, in almost all cases (hardware or software), not going to happen synchronously before the return of the Promise and continuation of the task pool. So callers should have a reasonable expectation of what the transformation of the data will look like. Since objects - such as ArrayBuffer - are passed by reference, callers can fully mutate the object throughout the lifetime of the Promise, so it's necessary, as spec authors, to indicate at what point in execution the state is accessed. In Web Crypto's case, we try to make it clear that any and all state that will be accessed before the return of the Promise object. Other specs (Web Audio and Web Font Loading come to mind), have not, and as such, have subtle issues in their spec that can lead to user-observerable, non-interoperable behaviours. > Also, is the a reason that the CryptoKey > parameter objects aren't cloned (probably deeply) to ensure that it isn't > mutated at the same time a buffer might be mutated? Let's follow up on public-webcrypto@. TL;DR: CryptoKey's are immutable holders of an internal object ( [[handle]] ). All ops work on the internal slots, which cannot be mutated. > If we're talking about any sort of real object graph (for example, a > CryptKey??) a generalized clone operation is much more problematic. We aren't, or more specifically, I'm not, and certainly not in this bug. I agree that other Promise-returning APIs may accept other forms of mutable objects, and those APIs may need to define at what timeslice/task event snapshots (if any) are taken of the object state for working with the API, and when/how object state is accessed. However, for fundamental ES types - those for which Web IDL spends significant time dealing with (in terms of the ES <-> IDL type conversions) - it would be nice to see %TypedArray% - which is as primitive as %Array%, %String%, %Boolean%, or %Number% are in ES6 - to have specific language in Web IDL to explain how it's used with Web IDL, and to afford Spec Authors ways to hook or customize that behaviour (eg: copies), if necessary. > BTW, on a pretty much separate matter I'm not really convinced > that you need to allow either an ArrayBuffer or a typed array > for all of these data arguments. A better fora for this is public-webcrypto@ / public-webcrypto-comments@ (or our WebCrypto bug tracker), where I'd be happy to address this feedback. -- You are receiving this mail because: You are on the CC list for the bug.
Received on Tuesday, 17 June 2014 21:39:59 UTC