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

On Mon, Jan 28, 2013 at 4:49 PM, 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 3:56:20 PM
>> Subject: Re: An initial editor's draft: high-level API
> ...
>> 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(...) {}
>>
> Ok, that is better yet. I'll have to figure out the WebIDL for that.
>
>> 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
>>
> Ah, cool.
>
>> >
>> >>
>> >> 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", ...);
>>
>
> OK, I have updated the draft, I specifically added each callback's IDL before the interface IDL, but will update for a promises-like interface tomorrow.
>
>>
>> >
>> >>
>> >> 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.
>>
>
> I made the key gen joseAlg optional for now, but can just assume we remove it altogether.
>
>> 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.
>
> gotcha.
>
>>
>> >
>> >> 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
>>
> I changed them already as well. Removed hash and simplified a bunch of other stuff.

Additional comments:

In https://dvcs.w3.org/hg/webcrypto-highlevel/rev/27bcbfdc4adf , you
added use cases to describe possible consumers of this API.

Your banking API suggests that data may be 'safely' stored in the
browser's local storage, including sensitive information like credit
cards, as a way to reduce the value of attacking the target.

However, doesn't this *raise* the risk, rather than reduce it, by
virtue of the fact that origin-based storage is origin-based? That is,
a reflected-XSS or stored-XSS attack against such a server could be
used to obtain the credit card numbers from untold thosands of users.
While it may not allow for the exfiltration of the complete database,
in practice, it's much, much easier to execute an XSS against a site
than it is to obtain the server database.

I also don't know how 'realistic' this use case is, given requirements
like PCI-DSS. Unless site operators could be "assured" of the nature
of the cryptography used, they wouldn't be able to trust it. And of
course, such assurance is impossible in a model where it relies on
trusting clients (eg: the whole 'how is the private key stored' debate
from the low-level API)

In your Web-based messaging example, where is the source javascript
for the private messaging feature obtained? From the server, I would
presume, right? If so, under what threat model is this meant to
protect against? The server? Network-level eavesdroppers? Accidental
logging? Deniable messaging?

In practice, it still requires establishing trust in the server (and
whatever system was used to securely deliver the JS - such as the CA
certificate), so if that's the threat model, I'm not sure how it's
addressed, unless you presume this to be an extension-only system. At
that point, you're then trusting the user agent and the extension
update mechanisms to be free of coercion or corruption - which is a
different threat model.

Just mentioning it because the use cases don't quite provide a clear
picture of the security assumptions this API is making, and those
assumptions directly influence the ability to apply this API to other
use cases that share or are compatible with those assumptions.

Received on Tuesday, 29 January 2013 01:00:10 UTC