Re: crypto-ISSUE-31: Problems with keys attribute of the Crypto interface [Web Cryptography API]

On Mon, Aug 27, 2012 at 4:34 PM, Web Cryptography Working Group Issue
Tracker <sysbot+tracker@w3.org> wrote:
> crypto-ISSUE-31: Problems with keys attribute of the Crypto interface [Web Cryptography API]
>
> http://www.w3.org/2012/webcrypto/track/issues/31
>
> Raised by: Wan-Teh Chang
> On product: Web Cryptography API

Hi Wan-Teh,

In the future, I think it might be good to raise separate ISSUEs if
there are multiple issues, even if they're closely related.

This makes it easy to ensure that each point is addressed and not lost.

>
> The keys attribute of the Crypto interface is specified as follows:
>
> interface KeyStorage {
>   readonly attribute unsigned long length;
>
>   getter Key getKey(unsigned long index);
>   deleter void removeKey(unsigned long index);
>   void clear();
> };
>
> interface Crypto {
>   ...
>   readonly attribute KeyStorage keys;
>
>   ...
> };
>
> This is the only key discovery method provided in the current API.
> The keys attribute has three problems.
>
> 1. All operations that may potentially block should use an async API.
> Getting the keys attribute of the Crypto interface is synchronous.
> However, the underlying operation may potentially block because disk
> or secure element access may be required to get the number of
> persistent keys, which is needed to compute KeyStorage.length.

Can you explain why you feel secure element access is or may be
required? This is not the intent.

window.crypto.keys tracks already authorized keys. It is not, as you
note, a means for discovering keys (which is a separate problem).

Within that space, regardless of how the underlying user agent stores
keys, it MUST store the association/knowledge that a PARTICULAR key
has been granted access to a particular origin. Whether this be
because the origin generated the key, because the key was imported
into that origin, or whether it was pre-provisioned out of band, and
whether this key is stored on disk, in the OS key store, or via some
proprietary mechanism is irrelevant to the fact that a user agent
needs to track origin authorizations.

That is, it should have the same "overhead" of document.cookie (and friends).

>
> Similarly, the getKey method of the KeyStorage interface is
> synchronous, but the underlying operation could require disk or secure
> element access.

Can you explain why this is?

The only way I can think would be the possibility of arbitrary user attributes.

>
> 2. The keys attribute returns all the keys even though the application
> may only want to look up a particular key. If the user agent has a large
> number of keys for the origin, it may be forced to do a lot of unnecessary
> work.

Thanks for raising this again.

This has been previously discussed on our 8/20 con-call, where it was
suggested that named property getter/setters -
http://www.w3.org/TR/WebIDL/#idl-named-properties

Thus, window.crypto.keys.getKey("foo") would return a key named "foo",
which would be the only key named "foo" for that key.

>
> 3. The KeyStorage interface forces the application to do a linear search
> for a key in the KeyStorage, even though the underlying key storage may
> be a hash table or structured database that supports more efficient lookups.
>
> Proposed solution:
>
> I propose we replace the keys attribute with a findKey method.
>
> interface Crypto {
>   ...
>
>   KeyFinder findKey(Dictionary criteria);
>   ...
> };
>
> The 'criteria' dictionary may have the following members, intended
> to match common Key attributes:
>   DOMString id;
>   AlgorithmIdentifier algorithm;
>   bool temporary;
>   bool extractable;
>   KeyUsage[] keyUsages;
>
>   // Other dictionary members will match user attributes inside
>   // Key.userAttributes
>   DOMString foo;
>   DOMString bar;
>   ...
>
> The members in the 'criteria' dictionary have the AND semantics: the
> KeyFinder finds the keys that match all the members of the 'criteria'
> dictionary.
>
> interface KeyFinder : KeyOperation {
>   void find();
> };
>
> KeyFinder.result is a Key[] array.
>
>
>

This appears to be a modified form of KeyQueryList strawman.

My concerns with this interface were documented in
http://lists.w3.org/Archives/Public/public-webcrypto/2012Aug/0161.html

Briefly, the following concerns:
- What if you want to query for a supported RSA key size.
AlgorithmIdentifier is unsuitable for this
- What if you want to match for negations
- Matching arbitrary attributes by "string" has a host of
canonicalization issues
  - What if a user attribute contains a Blob? How should that be canonicalized?
  - Likewise, what if a user attribute contains a UInt8Array? How
should the DOMString (which is UTF-16) be interpreted? As the base64
encoding? As a "fat ASCII" string, where the code points must be in
the range of 0 - 255?
  - What about boolean attributes? Do you match on string values "1"
or "0"? "true" or "false"? Rely on implicit conversion of bool to
string?
- Do we need to define a grammar for attributes?

Additionally, there's the broader question of the interface for key
authorization (eg: finding a key for a certificate) vs existing key
iteration.

I believe that trying to define a sensible filtering/querying language
is a subtly large problem, and thus would seek postponement until
after FPWD.

I (perhaps naievely) believe that the number of keys per origin will
remain sufficiently low that even a linear search is of quite suitable
performance, and thus specifying a format for querying perhaps a
distraction to the more troubling areas needing consensus.

Received on Tuesday, 28 August 2012 00:26:49 UTC