Re: ISSUE-3: Algorithm discovery

Perhaps we should change it to an async method. I think there is value in being able to avoid long/costly operations.

I can imagine some use of the API would begin with a test and inside the test oncomplete handler you begin the long running operation...

var key = localStorage.ALICE_KEY;

var message = "s3kr3t m3ssag3";

function onEncryptComplete(aCipherData) {
  // send message to server, etc...
}

function onAlgTestComplete(isSupported) {
  if (isSupported) {
    var stream = window.crypto.encrypt("RS256", key);
    stream.oncomplete = onEncryptComplete;
    stream.processData(message);
    stream.complete();
  }
}

var supportTest = window.crypto.supports("RS256", key);
supportTest.oncomplete = onAlgTestComplete;
supportTest.verify();


So the IDL might be:

[Constructor, Constructor(Algorithm algorithm, Key? key)]
interface AlgSupport : EventTarget {
attribute [TreatNonCallbleAsNull] Function? onerror;
attribute [TreatNonCallableAsNull] Function? oncomplete;
void verify();
};

Does this help? Does anyone think we do not need a "supports" API at all? Is there a better approach? 

Cheers,

David

----- Original Message -----
> From: "Ryan Sleevi" <sleevi@google.com>
> To: public-webcrypto@w3.org
> Cc: "David Dahl" <ddahl@mozilla.com>, "Michael Jones" <Michael.Jones@microsoft.com>
> Sent: Monday, July 9, 2012 8:26:47 PM
> Subject: ISSUE-3: Algorithm discovery
> 
> In the original straw-man and current draft, I proposed an API
> 
> bool supports(Algorithm algorithm, optional Key key);
> 
> This was to allow determining whether or not a given algorithm was
> supported, without having to actually create a CryptoStream object.
> The
> intent was to provide a way to discover whether the necessary
> complete set
> of ciphers was available for an application, before beginning
> potentially
> expensive operations (key generation, data download, key discovery
> that may
> result in user interaction, etc).
> 
> However, as some have pointed out, there are implicit facilities for
> algorithm discovery, by virtue of the fact that
> .encrypt/.decrypt/.sign/.verify need to have some well-defined
> behaviour
> for handling invalid or unsupported Algorithms. It has also been
> raised
> that whether or not a given algorithm is supported is dependent upon
> the
> key being used, although I believe I addressed that point via the
> optional
> "Key" parameter, since it allows a user optionally to determine if a
> particular key supports the algorithm, rather than just whether or
> not an
> implementation exists.
> 
> However, I'm now thinking that the currently defined synchronous
> interface
> is neither desirable nor sufficient. It seems to me that, for at
> least some
> key storage types, determining whether or not a particular algorithm
> is
> supported may involve some form of user interaction or, in the case
> where
> key storage is backed by hardware, some form of hardware
> communication. For
> example, if using PKCS#11, this may involve calls to
> C_GetMechanismInfo,
> which may involve talking to a token/slot.
> 
> These calls may be slow - especially if other programs are using the
> token
> or key storage mechanism (including software storage systems that
> need to
> have locks) - so it would seem like this should be an asynchronous
> call. It
> would also seem that my straw man proposal fails to distinguish the
> uses of
> a particular algorithm - for example, a key may only support
> verification,
> but not signatures. These sorts of scenario arises even if raw keying
> material is exposed and implementations are fully software, I
> believe,
> since there are still limitations on how a key may be used.
> 
> Ultimately, this means that the current proposed synchronous API is
> likely
> insufficient.
> 
> Based on what was proposed in the strawman-now-draft, this would seem
> to
> imply that the error/exception for an invalid Algorithm would not be
> able
> to be raised until the first call to .processData on the
> CryptoStream.
> 
> eg:
> try {
>   var stream = window.crypto.encrypt("RS256", key);
> } catch (err) {
>   if (err instanceof InvalidAlgorithmException) {
>     // "RS256" does not parse as a valid Algorithm
>   }
> }
> stream.onerror = function(err) {
>   if (err instanceof UnsupportedAlgorithmException) {
>     // "RS256" is parsed, but either the key or the underlying
> implementation doesn't support it.
>   }
> }
> // Until this is called, it's unknown whether or not "stream" will
> actually
> work. If it ends up failing, stream.onerror will be called.
> stream.processData(...);
> 
> 
> Note that none of the above semantics would necessarily be altered by
> a
> MUST-IMPLEMENT registry (ISSUE-1), since there would still need to be
> some
> form of error handling for invalid constants/strings and for
> unsupported
> key+algorithm+operation tuples.
> 
> Further, attempting to discover an algorithm by sending 'junk' data
> (constants or random) may result in user agents having to interact
> with the
> user, since there may be security concerns about even calling
> .processData() on an object (regardless of .complete()), which is
> some of
> what ISSUE-2 may be related to.
> 
> As an implementer, the above semantics look both undesirable and
> limiting
> to potential consumers. How do others in the WG feel? Should there be
> an
> explicitly asynchronous call to determine whether or not an
> algorithm/algorithm+key pair/algorithm+key+operation tuple is
> supported,
> without requiring .processBytes()? Are there alternate proposals that
> would
> simplify or could replace the above API?
> 
> Cheers,
> Ryan
> 

Received on Tuesday, 10 July 2012 16:09:55 UTC