This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 23728 - CryptoOperationData can be mutated during operation
Summary: CryptoOperationData can be mutated during operation
Status: RESOLVED FIXED
Alias: None
Product: Web Cryptography
Classification: Unclassified
Component: Web Cryptography API Document (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal
Target Milestone: ---
Assignee: Ryan Sleevi
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-11-05 18:02 UTC by Alexey Proskuryakov
Modified: 2014-06-16 23:21 UTC (History)
3 users (show)

See Also:


Attachments

Description Alexey Proskuryakov 2013-11-05 18:02:59 UTC
Typed arrays are mutable, and WebCrypto algorithms are asynchronous. To avoid races, WebCrypto needs to specify how to prevent data from being changed underneath an algorithm.

A couple alternatives:

- The operations implicitly freeze the typed arrays passed to them. As far as I can tell, this should be just fine for all use cases - e.g. one is unlikely to modify data they just signed.

- The arrays are made copy on write. I've been getting strong pushback against this due to design and performance concerns. Other applications of typed arrays don't need this, but they'd have to pay the price for extra checks.

One way or another, not specifying anything is clearly wrong.
Comment 1 Mark Watson 2014-03-03 19:17:05 UTC
This is also an issue in the EME and MSE specification. Apparently Web Audio may also have solved this. It would be good to have a common approach across specifications.
Comment 2 Ryan Sleevi 2014-05-12 03:25:06 UTC
So, the Web Audio solution isn't fully applicable here.

Web Audio only takes ArrayBuffer's as inputs, and describes an algorithm that is not clear if it's actually legal. That is, the algorithm ( from https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#methodsandparams-AudioContext ), is roughly

- Temporarily mark [input buffer] as neutered
- Perform some asynchronous operation
- Restore [input buffer] to it's original, un-neutered state.

That doesn't work for CryptoOperationData, which may take an ArrayBufferView, for the reasons described in https://www.khronos.org/registry/typedarray/specs/latest/#9.3 - Cloning an ArrayBufferView - although the language in ES6 (which is where TypedArrays now live - http://people.mozilla.org/~jorendorff/es6-draft.html#sec-structured-data - with the transferrable semantics in http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#transferable-objects )

Implementing something like the Typed Array transfer semantics isn't desirable in general, for consider a use case like digest(). Neutering the original object forces the copy semantics onto the caller, which then makes memory management more difficult to reason about (as it relates to reasoning about all the scopes both the original buffer and its clone are viable in).

In order to resolve this, I've made it explicit that the asynchronous operations operate on a copy of the data. This was included in the pre-Promises version of the specification, as well as the "sequence<CryptoOperationData>" form.

Alternative suggestions are welcome, but probably with accompanying proposed spec text.
Comment 3 Boris Zbarsky 2014-05-12 03:35:37 UTC
> that is not clear if it's actually legal.

It's not legal.  I ran into that recently too, and asked the people working on web audio in Gecko to raise a spec issue.

I believe making a copy of the incoming data here before going async is the right thing to do.