Re: An initial editor's draft: high-level API

On Mon, Jan 28, 2013 at 11:37 AM, David Dahl <ddahl@mozilla.com> wrote:
> ----- Original Message -----
>> From: "Ryan Sleevi" <sleevi@google.com>
>> To: "David Dahl" <ddahl@mozilla.com>
>> Cc: "public-webcrypto" <public-webcrypto@w3.org>
>> Sent: Monday, January 28, 2013 12:33:20 PM
>> Subject: Re: An initial editor's draft: high-level API
>>
>> On Mon, Jan 28, 2013 at 7:50 AM, David Dahl <ddahl@mozilla.com>
>> wrote:
>> > Hello All,
>> >
>> > An initial high-level API draft is here:
>> > https://dvcs.w3.org/hg/webcrypto-highlevel/raw-file/tip/Overview.html
>> >
>> > Naturally, this draft is missing a few things, details, etc. Some
>> > early feedback indicates that "sign" and "verify" are redundant
>> > with encryptAndSign and verifyAndDecrypt.
>> >
>> > The object and method naming needs work as well. Your feedback and
>> > criticism is eagerly awaited.
>>
>> I am having a hard time understanding what makes this proposal
>> "high-level", based on your specification:
>>
>> 1) You do not specify what the values returned are to callbacks. For
>> example, does .onProtect return a JWE-JS on onProtectComplete?
>> 2) Your callbacks do not seem to permit multiple parallel operations:
>>
>> window.crypto.highlevel.onProtectComplete = function(...) { }
>> window.crypto.highlevel.onProtectError = function(...) { }
>> window.crypto.highlevel.protect("a", "JWA-ALG-HERE");
>> window.crypto.highlevel.protect("b", "BAD-JWA-ALG-HERE");
>
> It does, you create an instance of the API like so:
>
> var cryptoAPI = new window.crypto.highlevel();
>
> The cryptoAPI object can be constructed multiple times thereafter for parallel ops.

I would recommend a Promises-like implementation, similar to what was
adopted in the low-level API. Having the factory object have multiple
independent methods is a pretty bad code-smell.

var promise = window.crypto.highlevel.protect("a", ...);
promise.oncomplete = function(...) {}
promise.onerror = function(...) {}

Then just 'start' the event in the next turn. This is also the example
used by IndexedDB (via the *Operation/*OperationSync objects).

Presumably in a worker you could do
promise.wait();
(to start and/or) to wait for synchronous completion

>
>>
>> In onProtectComplete and onProtectError, how do I know which was the
>> good message and which was the bad message? Am I relying on the
>> ordering of the calls?
> Perhaps "onProtectComplete" should be re-named "onProtectSuccess"

That wasn't the concern I had. It was more to the fact that one may
succeed, one may fail, and I didn't see a way to disambiguate between
them. The fact that highlevel is a constructed object makes it
somewhat clearer, but the API as spec'd doesn't make it clear if only
one operation-per-object in flight is permitted at a time.

eg, is the following code valid:

var obj = window.crypto.highlevel();
obj.onProtectComplete = function (...) {}
obj.onProtectError = function (...) {}
obj.protect("a", ...);
obj.protect("b", ...);


>
>>
>> 3) This does not seem to actually be high-level, in that it still
>> forces the caller to make decisions about algorithms throughout the
>> API, a point which I understood the high level was intentionally
>> intending to entirely abstract. You do not, for example, want to
>> encourage developers to use PKCS#1 v1.5 in new applications, but
>> that's effectively what this API does (as PKCS#1 v1.5 is the only
>> REQUIRED to implement in JOSE). What is the motivation for this, and
>> is this necessary? Isn't it better to hide these security parameters
>> entirely, and let the user agent make the most informed security
>> decision based on the security policy of the browser?
>
> I have been thinking about how to allow JOSE interop and also not require the user to make decisions about algorithms. Perhaps the browser makes all of the algorithm decisions, with the ability to optionally specify a JOSE algorithm. Also, the public keys are returned as JWKs indicating (some) JOSE interop. I also want this API to operate at a higher level. I hope Richard and Mike weigh in here.

I think if we want to talk about high-level, then the developer should
not be exposed to algorithms. It should just project messages.

Rather than treating interop between the client/server as a decision
to be solved for every application, treat interop as an issue between
the server & the user agent. That is, don't require the client
application to worry about crypto at all.

>
>> 4) You've specified a hash interface, but this seems entirely
>> redundant with the existing specification, which already permits JOSE
>> algorithms.
> I would not be opposed to removing hash()
>
>> 5) onProtect takes arguments in the form (aPlaintext, aJOSEAlg), but
>> onUnprotect takes them in (aKeyID, aPlaintext).
>>   a) Shouldn't onUnprotect's argument be named aCiphertext
> Yes.
>
>>   b) Shouldn't the order of the arguments be symmetrical between the
>>   the API
> Yes.
>
>> 6) Same for the lack of symmetry between sign()/verify()
> Yes. Also, it may also make sense to drop sign and verify altogether.

Depends.

NaCL ( http://nacl.cr.yp.to/index.html ) provides the following (with
the low-level web crypto equivalents):
1) Public/Private key encryption (eg: RSA-OAEP)
2) Public/Private key signatures (eg: RSA-PSS)
3) Secret key authenticated encryption (eg: AES-GCM)
4) Secret key streaming encryption (eg: RC4)
5) Secret key authentication (eg: HMAC)

SJCL ( http://crypto.stanford.edu/sjcl/ ) provides the following:
1) Password-based key derivation
2) Authenticated encryption (CCM & OFB2 - the latter with patent
concerns, despite Rogaway's comments)
3) A convenience function that combines these two into "password",
"data", with a 'secure' set of default params

>
>> 7) You make use of DOMString in the following methods:
>>   a) encryptAndSign (aPlainText)
>>   b) protect (aPlaintext)
>>   c) unprotect (aPlaintext - see 5)
>>   d) sign (aClearData)
>>   e) verify (aDataToVerify)
>> How is this data supposed to be canonicalized? How is arbitrary
>> binary
>> data supposed to be encoded? What about decoded?
>
> While I would like to make the interface as simple as possible (using strings), this is an issue that may require the use of ArrayBufferViews after all. I am unsure how to make DOMStrings viable here.

http://encoding.spec.whatwg.org/ ?

>
> Thank for the feedback and pointing out errors! I will update the draft accordingly. Also, __agl on twitter suggested I use "seal" and "open" for "protect" and "unprotect". I think these are better names.

+1

>
> Regards,
>
> David

Received on Monday, 28 January 2013 21:56:48 UTC