Re: Possible "key discovery" specification

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
  },
});

>
>
> > 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.

>
> > 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.

>
> >
> > 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)

>
> 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 18:23:26 UTC