- From: Ryan Sleevi <sleevi@google.com>
- Date: Wed, 21 Nov 2012 11:50:16 -0800
- To: Harry Halpin <hhalpin@w3.org>
- Cc: Mark Watson <watsonm@netflix.com>, "public-webcrypto@w3.org Group" <public-webcrypto@w3.org>
On Wed, Nov 21, 2012 at 11:30 AM, Harry Halpin <hhalpin@w3.org> wrote: > On 11/21/2012 03:55 AM, Ryan Sleevi wrote: >> >> On Tue, Nov 20, 2012 at 6:14 PM, Mark Watson <watsonm@netflix.com> wrote: >>> >>> All, >>> >>> Some Holiday (for those in the US) reading as promised ... >>> >>> Following the decision at the Lyon face-to-face, KeyStorage is no longer >>> required for the storage of "temporary" keys generated or imported by the >>> page (these can be stored in IndexedDB or in future storage mechanisms). >>> However, KeyStorage provides the only mechanism in the FPWD to obtain Key >>> objects for pre-provisioned keys. >>> >>> ISSUE-31 describes a few problems with KeyStorage. Below are two >>> proposals to address these: >>> >>> Proposal (A): remove KeyStorage and define a new key import algorithm for >>> this purpose >> >> I don't believe Proposal (A) is intuitive or right for the web >> platform at all. You're not importing a key. The key already exists. >> You're discovering a key which you know exists but do not have access >> to. >> >>> Proposal (B): remove KeyStorage and define a new method to create Key >>> objects (provisionally called createKeyAccessor, because we are "accessing" >>> a key, not "importing" the key itself.) and then define an algorithm for use >>> with this method. >> >> Beyond naming concerns (Accessor is quite generic), I *strongly* >> disagree with the use of AlgorithmIdentifier and AlgorithmParameters >> here. You're not describing a cryptographic algorithm. You're >> describing a vendor-specific extension. Let's call a spade a spade, >> but not call everything a "tool" just because you can argue the label >> fits. >> >> I feel this encourages the exact design pattern that I repeatedly >> expressed concerns about - namely, it creates and encourages an >> arbitrary set of key discovery mechanisms. I strongly disagree with >> that. I believe we should have a single key discovery mechanism. >> >> Let's put it a different way. This is the quintessential definition of >> Vijay's "void dovoid(void*)" API. The "KeyAccessor" hides completely >> different functions via a single function stub - making it more or >> less impossible for developers to reasonably determine feature >> support. This runs counter to every JS API. It's bad enough that >> algorithms do it - but as was discussed at length, this is because >> algorithm capabilities are not gated on user agent, but on the Key >> object itself. This functionality is entirely gated on the user agent >> - thus there is no reason that it should be an API like the other >> algorithms. >> >> While I appreciate the effort to bring text, I think this highlights >> what I was afraid of about trying to find something that is right for >> the web platform. >> >> If we're going to have a "DoVoid" function (a design decision I >> strongly disagree with), just make the parameters themselves the >> "DoVoid". That is, getKeys(some param dict, some callback). There's no >> need to create a separate object to hold state, there's no need to try >> to wrap the param dict in the aegis of >> AlgorithmIdentifier/AlgorithmParameters. >> >> My biggest concern remains what I've expressed repeatedly - >> introducing (more) optional functionality into the core spec, whether >> it's disguised in the terms of AlgorithmIdentifier/AlgorithmParameters >> or in the DoVoid via a set of optional-to-implement parameters, is >> deeply concerning for us. It just kicks the can of the API design down >> the road - by not making any of the hard decisions necessary - but >> then makes it further complex for desktop/mobile browsers to develop >> or implement an API that's friendly to the open web platform, because >> "The web crypto API already has a means for key discovery, why invent >> another" >> >> IF we're going to tackle key discovery (a point that, based on >> timelines and interest from desktop/mobile browser vendors), then I >> there should be *one* set of mandatory-to-implement key discovery >> parameters, with a single MTI key discovery API. If you are going to >> support arbitrary forms of key discovery, do it in a way that's right >> for the web - new methods that can easily be feature tested, not one >> giant API. >> >> Certainly, as repeatedly expressed during the F2F, I think trying to >> match the current API is an inherently bad idea, given that the >> current API is (as repeated by every browser vendor) quite unusable at >> this point and needs to be fixed. >> >>> Briefly, the pros and cons of the two proposals are: >>> >>> (A) >>> pros: the new text is restricted to a new algorithm section. The >>> same pattern could be used in future for tokens, smart cards etc. >>> cons: "import" is a misnomer because the key itself is not moved >>> into the UA. We have to overload the key parameter of createKeyImporter to >>> specify the key name >>> >>> (B) >>> pros: cleaner (addresses the cons above). The same pattern could >>> be used in future for tokens, smart-cards etc. >>> cons: more text (new KeyOperation object, new Crypto method) >>> >>> Note that I also plan to bring improved privacy text based on the >>> discussions at the face-to-face and subsequently. >>> >>> Proposal (A) >>> ========= >>> >>> 1) In Section 10 (Key interface), remove the id attribute >>> >>> 2) Delete Section 17 (KeyStorage) >>> >>> 3) Section 18, Crypto interface: remove keys attribute and section >>> 18.1.10 >>> >>> 4) Add a new section: >>> >>> "23.3.X Origin-specific named key access >>> >>> 23.3.X.1 Description >>> >>> The string "OriginNamedKey" is used to identify the origin-specific named >>> key access algorithm. UAs may support access to named origin-specific keys, >>> for example pre-provisioned keys. These may be external to the UA. Naming >>> schemes are out-of-scope of this specification. As examples, UAs may provide >>> access to UA or platform provided pre-provisioned keys for specific origins, >>> named according to the requirements of that origin. Another example would be >>> a UA-specific capability to provide one or more origin-specific keys to any >>> origin, with UA-defined names. >>> >>> 23.3.X.2 Registration >>> >>> The recognized algorithm identifier for this algorithm is >>> "OriginNamedKey". >>> >>> Operation | Parameters | Result >>> ---------------------------------------- >>> importKey | None | Key? >>> >>> 23.3.X.3 Operations >>> >>> Import Key >>> >>> When importing a key, the resulting KeyImporter shall behave as >>> follows: >>> >>> 1. Upon invoking import: >>> 1. If no key exists with a name equal to the contents of the key >>> parameter to the createKeyImporter call raise an error and terminate the >>> operation. >>> 2. Let result be a Key object providing access to the key with the >>> specified name. The temporary attribute of the Key shall be false. The >>> extractable attribute shall be true if and only if both the extractable >>> parameter to the createKeyImporter call was true and the key supports >>> extraction. The key usages shall be the intersection of the key usages >>> specified in the keyUsages parameter of the createKeyImporter call and the >>> key usages supported by the key." >>> >>> NOTE: we may instead simply require that the usages equal those supported >>> by the key. >>> >>> 5) Add example code, tbd >>> >>> Proposal (B) >>> ========== >>> >>> 1) In Section 10 (Key interface), remove the id attribute >>> >>> 2) Delete Section 17 (KeyStorage) >>> >>> 3) Add new Section X, after existing Section 16 >>> >>> "Section X: KeyAccessor interface >>> >>> interface KeyAccessor : KeyOperation >>> { >>> void get(); >>> };" >>> >>> 4) Section 18, Crypto interface: >>> - remove keys attribute >>> - add new method >>> >>> KeyAccessor createKeyAccessor( AlgorithmIdentifier? algorithm, >>> bool extractable = false, >>> KeyUsage[] keyUsages = []); >>> >>> 5) Add new section after 18.1.9 >>> >>> "18.1.Z The createKeyAccessor method >>> >>> The createKeyAccessor method returns a new KeyAccessor object that will >>> provide access to keys not originally created using the Crypto API (i.e. not >>> created with import, generation or derive methods.) It must act as follows: >>> >>> 1. If algorithm is specified, let normalizedAlgorithm be the result of >>> processing algorithm according to >>> the algorithm normalizing rules. >>> 2. If algorithm is specified and if normalizedAlgorithm does not >>> describe a registered algorithm throw a >>> NotSupportedError and terminate the operation. >>> 5. Return a new KeyAccessor object S with the following >>> characteristics: >>> 1. S.result = null >>> >>> Keys created with this method SHALL be subject to the extraction and >>> usage constraints of the key >>> itself. The extractable argument SHALL NOT be honored if the key itself >>> does not allow extraction of the key data. The >>> key's usages SHALL consist of the intersection of the keyUsages argument >>> and the usages supported by the key itself." >>> >>> NOTE: we may instead simply require that the usages equal those supported >>> by the key. >> >> Both keyUsages and extractable should be parameters for discovery. >> Asking for keys of (X AND Y) but getting keys of (Y OR X) is >> inherently error prone. >> >> If they are discovery parameters, then they should be in the >> parameters dictionary - not as standalone args. This applies for both >> KeyUsage and extractable. >> >>> 4) Add a new section: >>> >>> "23.3.X Origin-specific named key access >>> >>> 23.3.X.1 Description >>> >>> The string "OriginNamedKey" is used to identify the origin-specific named >>> key access algorithm. UAs may support access to named origin-specific keys, >>> for example pre-provisioned keys. These may be external to the UA. Naming >>> schemes are out-of-scope of this specification. As examples, UAs may provide >>> access to UA or platform provided pre-provisioned keys for specific origins, >>> named according to the requirements of that origin. Another example would be >>> a UA-specific capability to provide one or more origin-specific keys to any >>> origin, with UA-defined names. >>> >>> 23.3.X.2 Registration >>> >>> The recognized algorithm identifier for this algorithm is >>> "OriginNamedKey". >>> >>> Operation | Parameters | Result >>> ---------------------------------------- >>> accessKey | NamedKeyAccessParams | Key? >>> >>> 23.3.X.3 ExtKeyImportParams dictionary >>> >>> dictionary NamedKeyAccessParams : AlgorithmParameters >>> { >>> >>> // The key name >>> >>> ArrayBufferView keyname; >>> }; >> >> Why not DOMString? This just furthers the comments of the "void*" >> part, since ArrayBufferView is a not only a fully opaque series of >> bytes, but regrettably developer-hostile (as shown in the example >> code). >> >> Naming wise, the addition of "Origin" seems redundant - the entire >> security premise of the API is origin-based keys. >> >>> >>> 23.3.X.3 Operations >>> >>> Access Key >>> >>> When importing a key, the resulting KeyImporter shall behave as >>> follows: >>> >>> 1. Upon invoking get: >>> 1. If no key exists with a name equal to the contents of the name >>> parameter raise an error and terminate the operation. >>> 2. Let result be a Key object providing access to the key with the >>> specified name." >> >> Redundant? Or how do you see this working, given that "name" is unclear >> here. >> >>> 5) Add example code, tbd >>> >>> ...Mark >>> >>> On Nov 19, 2012, at 1:14 PM, Mark Watson wrote: >>> >>>> On Nov 19, 2012, at 11:30 AM, Ryan Sleevi wrote: >>>> >>>>> On Mon, Nov 19, 2012 at 10:27 AM, Mark Watson <watsonm@netflix.com> >>>>> wrote: >>>>>>> >>>>>>> As mentioned previously, this does not sound like a suitable approach >>>>>>> to addressing the technical concerns raised. >>>>>> >>>>>> You mentioned that you did not like overloading the existing >>>>>> import/export, but I didn't see any comments from you against the idea of >>>>>> casting different query/discovery mechanisms as 'algorithms'. Do you object >>>>>> to that approach generally ? Could you elaborate ? >>>>>> >>>>>> …Mark >>>>> >>>>> Every browser vendor that has commented has (rightfully) raised >>>>> concerns about optional algorithms. "Optional" is generally seen as >>>>> bad for the web platform. I've already received suggestions from some >>>>> that the way to address algorithm regulatory/technical concerns >>>>> motivating algorithm optionality would be the wholesale >>>>> enabling/disabling of the feature, rather than having algorithms be >>>>> optional. This is conceptually similar to WebGL, in which if a video >>>>> card does not support feature X, the entire WebGL suite is disabled >>>>> (or the browser software-fills it in). While not wanting to re-open >>>>> the algorithm debate at this point, I provide it as a reasonable point >>>>> to demonstrate the growing concern about how effective the API will be >>>>> with optionality, and why more optionality is a non-starter. >>>>> >>>>> As related previously, I've hopefully made it clear my own view that a >>>>> model of optionality - modeled after algorithms or otherwise - is >>>>> pretty much a non-starter for the main spec from an implementer's >>>>> perspective, for reasons such as above. If the WG reaches consensus to >>>>> going further down the rabbit hole of "optionality", then we should be >>>>> talking modules and separate specs (each of which MUST be wholly >>>>> implemented), rather than a giant mix-and-match free for all in a >>>>> single spec. > > > Note that this is an interesting change of position re algorithms as decided > earlier, i.e. where we would not have have any required algorithms but > instead have a small set of recommended ones and then a larger set of > optional ones. We would test for all in our test-cases but need only the > recommended ones to demonstrate > > Yet I don't think my attempt to address Mark's proposal has anything to do > with optionality per se. What I was suggesting was not that we should > implement a purely optional solution to ISSUE-31, but that in order for the > pre-provisioned use-case to work without a separate KeyStorage, we need to > clarify how key import/export works. It seems to me that Mark's proposals > are a step in that direction. Harry, this is not key import/export. This is key discovery. The two are very different. This is not taking key data and bringing it in - this is about taking key metadata and discovering the pre-existing key data. My position on optionality is the same since day one. I find it abhorrent and undesirable, but in the case of algorithms+keys, a necessary evil for supporting arbitrary key storage. This is the same motivation that wanted to explore window.crypto.aes, which demonstrably doesn't work, but at least provides a better experience for web developers. If you recall during the Mountain View F2F, my position even then was not even that we should support such keys in the draft (smart card or pre-provisioned), but that we should continue the thought experiment of making sure to consider exactly how such keys *would* work, when they are *later* spec'd. That said, I do not think it should be used as the model for adding optional features. There are already plenty of ways to do that in the web platform today without having to resort to the notion of Algorithms (of which key discovery is most definitely not). I absolutely think key discovery should be approached separately, and should be approached holistically. It needs the involvement of all parties with a vested interest in key discovery - whether it be smart card, certificate, Kerberos tickets, or pre-provisioned keys (of which there are many types beyond just Netflixes/the TV WG's). That really is a separate topic that bears discussion - but I don't think it's a good idea to say "void* dovoid(void*) for now, and it's extensible, so others can figure their stuff out later".
Received on Wednesday, 21 November 2012 19:50:44 UTC