Re: Named key access (was Re: ISSUE-31 Re: KeyStorage and Pre-provisioned Keys: A proposal )

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.


>>>>
>>>> Regardless though, given the significant (complete?) overlap between
>>>> pre-provisioned and pre-existing keys, it seems like a single, common,
>>>> mandatory API is absolutely possible to devise.
>>> Ok. I think in this case most of what you say above about "optionality" becomes moot. If a device doesn't have, doesn't support, doesn't care about some particular kind of key, then any kind of key query is going to return "not found". If it reduces "optionality" we can specify that this is what should be returned in all cases where a Key object can't be returned, and don't break out "algorithm not supported" as a separate case.
>>>
>>> I appreciate that we should not introduce optionality through our work on the API, but there do exist things that are beyond our control, like devices with different capabilities.
>>>
>>> …Mark
>>>
>>>
>>>
>>

Received on Wednesday, 21 November 2012 19:30:51 UTC