- From: Richard Barnes <rlb@ipv.sx>
- Date: Mon, 10 Mar 2014 23:11:27 +0000
- To: "public-webcrypto@w3.org" <public-webcrypto@w3.org>
- Message-ID: <CAL02cgQC2OKJBN6qAE4fkEwQmcAEzcVBQkN+ZXEH6SwdSAHbqg@mail.gmail.com>
TL;DR: Usage of Dictionary inheritance for Algorithms is broken. Should use WebIDL object type or callback interfaces instead. BACKGROUND: In the current spec, algorithm identifiers and parameters are passed to encrypt(), decrypt(), etc. using dictionaries that inherit from Algorithm, which is itself a dictionary type. For example: dictionary Algorithm { DOMString name; } dictionary AesCbcParams : Algorithm { CryptoOperationData iv; } typedef (Algorithm or DOMString) AlgorithmIdentifier; Promise<any> encrypt(AlgorithmIdentifier algorithm, ... ) PROBLEM: According to the WebIDL spec for handling of dictionary types, the implementation is required to create the dictionary object by copying out of the source object the fields specified in the type definition. http://www.w3.org/TR/WebIDL/#es-dictionary For WebCrypto, this means that polymorphism via inheritance of dictionaries doesn't work. If someone creates a dictionary that matches AesCbcParams and passes it to encrypt(), then the WebIDL implementation will only store the "name" field, and throw everything else away. Anything using the WebIDL object will not be able to see the "iv" parameter. As far as implementation: I discovered this bug while trying to implement using the Firefox WebIDL implementation, so clearly Firefox has this problem :) It appears that Chromium is internally treating "algorithm" arguments as generic objects (not following the WebIDL spec for dictionaries), then using a "parseAlgorithm" method to pull out relevant information. PROPOSED RESOLUTION: It seems to me that we have a couple of options here. 1. "typedef object Algorithm" - Don't have the WebIDL handle any of the internal structure of Algorithm objects, but instead lay this out in the text of the spec. In this case, there's no inheritance to speak of, just lists of what parameters must be present in each use of Algorithm. We would need to specify at what point in the process values are extracted from the object. 2. "callback interface Algorithm" - This would use inheritance and have the expected behavior, since callback interfaces keep around a copy of the provided JS object. However, there might be some weird behaviors if people pass in exotic objects, e.g., side-effects or changing values. Also, the spec would need to carefully define exactly when the properties are accessed, and all per-spec access to the properties would need to be done on the main thread, since it needs to be able to run script. I have a slight preference for (2). It continues to delegate most of the work to WebIDL, and it seems unlikely that people will do exotic enough things to cause trouble, given that the way WebCrypto uses these objects is fairly straightforward. --Richard
Received on Monday, 10 March 2014 23:11:54 UTC