Re: Possible "key discovery" specification

On Dec 10, 2012, at 10:22 AM, Ryan Sleevi wrote:

> On Mon, Dec 10, 2012 at 9:20 AM, Mark Watson <watsonm@netflix.com> wrote:
>> 
>> 
>> On Dec 10, 2012, at 1:25 AM, Ryan Sleevi wrote:
>> 
>>> On Sun, Dec 9, 2012 at 11:34 PM, Mark Watson <watsonm@netflix.com> wrote:
>>>> All,
>>>> 
>>>> To further this discussion, I created a draft of a possible "key discovery"
>>>> specification. This draft covers only named origin-specific pre-provisioned
>>>> keys, since this is the case I am familiar with. However, I would see no
>>>> problem extending this for other forms of key (so long as there are
>>>> proponents prepared to do the implementation and specification work on the
>>>> appropriate timescales.)
>>>> 
>>>> I couldn't get this committed to a repository giving you all access via a
>>>> URL, so the HTML of the specification is attached.
>>>> 
>>>> Best regards,
>>>> 
>>>> Mark
>>>> 
>>>> 
>>>> 
>>> 
>>> Mark,
>>> 
>>> Thanks for this. We should make sure you have appropriate Mercurial
>>> access (everyone in the WG should).
>>> 
>>> A few thoughts:
>>> 1) KeyArray seems to implement a read-only pseudo-array. It seems like
>>> you could just have the IDL say "void complete(Key[] keys)", and let
>>> it be a "Real" array type. After all, once it's returned to the
>>> caller, just let them treat it like a normal array type (and do things
>>> like slice and splice and whatever other array modification they want)
>> 
>> Ok.
>> 
>>> 2) There's no form of error feedback (eg: an onerror callback). It
>>> would seem applications would have to, at best, guess by using
>>> .setTimeout(). Is that intentional?
>> 
>> Yes and no. It's intentional that there's no error callback. But the intention is that the single callback will always be called, possibly with an empty list.
>> 
>> I'm not sure there are any "error" cases as such. Either the key can be found, or it cannot (for some reason). Can you think of any cases where we want to expose the difference between key-not-found and some error case ? Are there any "temporary" errors that might be resolved by retrying ?
> 
> 
> Thanks for clarifying that. From the reading, it wasn't clear if
> oncomplete was always called, and that if it wasn't found, it'd be an
> empty array. I had assumed the intent was that oncomplete would only
> be called when length > 0.
> 
> As an error handling mechanism, I have no strong opinions on this. It
> "seems" that oncomplete only being called when .length > 0 and onerror
> being called for any other reason at least lets the callers formally
> separate out the error handling, but I'm not sure how significant that
> is.
> 
> That is, compare the following
> 
> function handleError() {
>  // Error handling here
> };
> getKeysByName({
>  name: 'foo',
>  oncomplete: function(keys) {
>    if (keys.length == 0) {
>      return handleError();
>    }
>    // Success here
>  },
> });
> 
> with
> getKsyByName({
>  name: 'foo',
>  onerror: function(event) {
>    // Error handling here
>  },
>  oncomplete: function(keys) {
>    // Success here
>  },
> });
> 
> In particular, my concern with having keys.length == 0 returned to
> oncomplete is the following dangerous code
> getKeysByName({
>  name: 'foo',
>  oncomplete: function(keys) {
>    var key = keys.get(0);  // Presumably, this throws an
> IndexSizeError if .length == 0, thus exploding subtlely
>  },
> });

I see the point. My only argument was that not finding a key isn't necessarily an "error" in the sense of something going wrong. There may be apps that work both with and without pre-provisioned keys (perhaps with more features if they are there. For example with Netflix you might get more HD content).

> 
>> 
>> 
>>> 3) It's not available to Workers, as I understand it. Perhaps you
>>> could have WorkerContext implement WindowCryptoKeys, although I'm not
>>> sure how SharedWorkerContext behaves there.
>> 
>> Are you proposing that it should be available to Workers ? (btw, how is the Crypto object itself made available to Workers, or is it ?)
> 
> Hrm, looks like I missed committing the change to enable "full" Worker support.
> 
> In the latest ED, this is done through the WorkerCrypto interface:
> 
> https://dvcs.w3.org/hg/webcrypto-api/raw-file/f5e8d9a3e18f/spec/Overview.html#WorkerCrypto-interface
> 
> However, the proposal is simply to have
> 
> partial interface WorkerGlobalScope {
>  readonly attribute Crypto crypto;
> };
> 
> Which exposes all of the Crypto methods to Workers. Since IndexedDB is
> available to Workers ( see
> http://www.w3.org/TR/2012/WD-IndexedDB-20120524/#requests ), you can
> use any Key object on the "main" thread or the "worker" thread.

Ok. Do you see any reason not to expose the getKeysByName to workers in the same way ?

Do I understand correctly that you plan to remove the WorkerCrypto and just expose Crypto directly in WorkerGlobalScope in a future draft ?

Btw, I have seen two ways to add new functionality (say newAttribute) to a pre-existing interface (OldInterface):

interface NewInterface {
	readonly attribute X newAttribute;
}

OldInterface implements NewInterface;

 --- or ---

partial interface OldInterface {
	readonly attribute X newAttribute;
}

What is the difference ?

> 
>> 
>>> 4) Having getKeysByName() return multiple keys seems a little
>>> confusing. For example, if getKeysByName({ name: 'myKey', ... }), and
>>> I get two keys back:
>>> 4.a) Are they ordered in a particular order. For example, is
>>> keys.get(0) always going to be the public key, and keys.get(1) always
>>> going to be a private key?
>>> 4.b) Are they supposed to be disambiguated via another means (such
>>> as an id attribute?). In the latest ED, I removed the ID attribute
>>> because it doesn't quite fit in the realm of 'arbitrary keys and
>>> arbitrary key storage'.
>>> 
>>> One way to resolve this might be
>>> interface NamedKey : Key {
>>> readonly attribute DOMString name;
>>> readonly attribute DOMString id;
>>> };
>> 
>> I assumed they would have attributes that disambiguated them, but the NamedKey suggestion is better.
> 
> The above presumes that the underlying storage cannot, for the
> lifetime of a Key object, ever change the 'name' or 'id' attribute.
> 
> The reason I mention this is the ambiguity I mentioned on the call
> today. Imagine the following scenario:
> 
> 1) Developer calls .getKeysByName({ name: 'foo' })
> 2) Developer gets two NamedKey objects back
>  keys.length == 2
>  keys[0].name === 'foo'
>  keys[1].name === 'foo'
>  keys[0].id === 'unique-1'
>  keys[1].id === 'unique-2'
> 3) Developer sticks them in IDB (hand wave here)
> 4) Underlying implementation "renames" keys[0].name from being 'foo'
> to 'old-foo'
> 5) When the user retrieves keys[0] from IDB, what is the value of keys[0].name
>  a) keys[0].name === 'old-foo' (the value at the time of retrieval)
>  b) keys[0].name === 'foo' (the value at time of structured clone)
> 6) How does the user agent implement/ensure the above, and what are
> the (synchronicity) concerns
>  a) ex: What happens if the implementation renames a Key while the
> object is held by the web app? Does the name change just then?
> 
> If .name may change due to the underlying implementation (that is,
> it's not a fixed-for-the-lifetime-of-the-key attribute), then I would
> suggest you *not* make it an attribute. Let it be implicitly handled
> by .getKeysByName() and make it the callers responsibility to
> 'remember' what the key was named if they're going to structured clone
> it.
> 
> If the .name IS immutable (and I presume .id is, otherwise all of
> these concerns apply to .id as well), then exposing it as an attribute
> makes sense, IMO.

There are scenarios where pre-provisioned keys are replaced. The question is how to deal with those in this API.

I'm inclined to say that the name and id of a NamedKey should be immutable, as this avoids the problems you describe above.

That means it's possible that a Key placed in some storage becomes divested of it's underlying cryptographic material - do we have a way to handle that ? (I would think that's possible in any case where the actual cryptographic material itself is not stored in the same storage as the Key object.)

Typically, when pre-provisioned keys are updated we would give them new names (perhaps the name contains a base name and a sequence number). It may be useful to allow wildcards in the name specifier for this case.

> 
>> 
>>> 
>>> With supporting text to provide clarification on what name contains
>>> and what ID contains (as well as structured clone definition, I
>>> believe)
>>> 
>>> With Key being structured cloneable, I just want to confirm that it's
>>> fine if someone does a .getKeysByName(...), gets a series of Key (or
>>> NamedKey) objects back, and then sticks them into IndexedDB. At that
>>> point, they "never" have to call getKeysByName() again, unless
>>> IndexedDB is cleared. That seems a nice "feature", but I wasn't sure
>>> if your use case dictated that Key/NamedKey objects returned by this
>>> should NOT be structured cloneable. If so, we'll have to proceed
>>> carefully here.
>> 
>> Yes, the intention is that you can structured clone these like any other Key. The only constraint with pre-provisioned keys is that the keying material itself stays where it is, but structured clone doesn't move the keying material, IIUC.
> 
> Correct. Structured clone says nothing about the underlying key
> material, just that you can get a Key object back that is in every way
> equivalent to the Key object you put in (eg: refers to the same Key).
> 
> If the underlying storage removes the cryptographic Key material, then
> that would presumably be detected during processing and return some
> sort of "invalid key error" (which the base spec should address
> regardless)

Ok, that answers the question above.

> 
>> 
>> btw, I must say I find the structured clone algorithm itself rather abstruse. Is there any material which explains why it is the way it is ? (the 'structured clone' and 'internal structured clone algorithm' links in your draft don't go anywhere).
> 
> Yeah, those are supposed to xref to the HTML spec.
> 
> In particular, see
> http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#safe-passing-of-structured-data
> to see the details of the algorithm (and the "internal structured
> cloning algorithm")
> 
> See ImageData/ImageBitmap for an example of specifying how individual
> attributes are serialized.
> 
> See also http://www.khronos.org/registry/typedarray/specs/latest/#9 to
> see how Typed Arrays (ArrayBuffer/ArrayBufferView) defines its
> structured clone algorithm.
> 
>> 
>>> 
>> 
> 

Received on Monday, 10 December 2012 19:03:10 UTC