Re: ISSUE-35 - Wrap/Unwrap - Why JOSE?

On Fri, Apr 26, 2013 at 5:32 PM, Mark Watson <watsonm@netflix.com> wrote:
>
>
> On Fri, Apr 26, 2013 at 4:21 PM, Ryan Sleevi <sleevi@google.com> wrote:
>>
>> Thanks for your quick response, Mark.
>>
>> Unfortunately, I find it still needs quite a bit of unpacking to get
>> to the meat of the issue. I've attempted to ask clarifying questions
>> from your remarks, and to make sure I've properly unpackaged the
>> requirements implicit in your statements.
>>
>> Please let me know if and where mistakes have been made.
>>
>> On Fri, Apr 26, 2013 at 3:43 PM, Mark Watson <watsonm@netflix.com> wrote:
>> >
>> >
>> > On Fri, Apr 26, 2013 at 2:50 PM, Ryan Sleevi <sleevi@google.com> wrote:
>> >>
>> >> Out of curiosity when reviewing wrap/unwrap, what technical reasons
>> >> are there to require the format be JOSE?
>> >
>> >
>> > 1) This is what was proposed and noone objected
>> > 2) There is no existing format for wrapping WebCrypto keys, which have
>> > attributes as well as keying material. So we have to create something
>> > new.
>> > Using JOSE, which already has an active community developing it is a
>> > much
>> > better choice than rolling our own format in WebCrypto
>>
>> #1 isn't a technical reason, but is useful information.
>>
>> If I can attempt to correctly distill #2 into a technical requirement,
>>
>> - Wrapped keys should preserve attributes
>>
>> This is not true for imported/exported keys, given the formats
>> supported, so this seems to be a *new* requirement being introduced.
>
>
> The attributes of a key are clearly visible on the Key object, so when you
> export a Key you also have access to the attributes.
>
> When you import a Key you specify the attributes of the Key in the call to
> importKey().
>
> The different between import/export and unwrap/wrap is just that the
> information flowing over the API is in-the-clear in the former case and
> cryptographically protected in the latter, not that the information is
> different.

So, I'm not sure we're in agreement in the means, but I think we're in
agreement in the concept.

In the case of import/export, the *calling application* specifies the
attributes (as part of the import/export). That is, these are not
transmitted in the format itself - they're handled by the calling
application.

That's the distinction I see between the wrap/unwrap proposal. In
wrap/unwrap, the attributes are no longer specified by the calling
application, but are transmitted in the format. That's a noticeable
difference between the two APIs.

While we're in agreement that the existing import/export doesn't
protect attributes (by virtue of not even *exporting* them), I'm not
sure that I'd agree that wrap/unwrap is the *only* way to
cryptographically protect them.

This again goes back to the security boundaries for this API. In my
mind, the web application must, forever and always, be part of the
security boundary. It is, in every sense, THE driving application.

As such, under this model, an application that wishes to decide the
attributes for (encrypted) keys that it will import can obtain those
attributes from a peer, and those attributes can be transmitted in a
manner that affords them integrity protection during transport.

However, once they enter the security boundary - the *web* application
- they can be protected and then imported.

This again goes back to what I suspect are our fundamental differences
of the security model - the pre-provisioned key use case would see the
web application *outside* the security boundary, while the web crypto
API would see the web application *inside* the boundary.

>
>>
>>
>> Is this a correct statement of the *technical* requirement being
>> introduced here though?
>
>
> You could think of the technical requirement being like import/export except
> that the information transferred is cryptographically protected. The essence
> of key wrap/unwrap is that the information is being transported between
> entities in possession of a particular key (or halves of a key pair).
>
> WebCrypto Keys consist of keying material and additional attributes, all of
> which can be transferred between script and UA unprotected using
> import/export and the Key object attributes themselves.
>
> I guess that, a priori, a WebCrypto wrap/unwrap capability may or may not
> encompass the attributes, but clearly since we have import/export a
> wrap/unwrap function is pointless if it doesn't encompass at least
> extractable.

I don't understand this comment. Our discussion at the F2F seemed to
have consensus that extractable=false keys would never be
wrap/unwrappable.

You can import a key and mark it unextractable.

I don't see why you say it's pointless.

> Our example explains why usages should also be included.

Protected from whom?

Protected during transport can fully be done by the existing API we have today.

It's only when you introduce "Protected from the application using the
API" that this becomes necessary, and I suspect that's a goal/security
constraint that we fundamentally disagree on.

But at least it further spells out the technical requirements - you
would prefer to treat the running application as untrusted.

>
>>
>>
>> >
>> >>
>> >>
>> >> To put it differently, if it is to be implemented, why can it not be
>> >> treated simply as a specialized form of export+encrypt/decrypt+import,
>> >> where, just like export/import, it takes a key format specifier.
>> >
>> >
>> > Someone objected pretty strongly to the original proposal for
>> > overloading
>> > import/export to perform wrap/unwrap as well. I wonder who that was ...
>> > ;-)
>>
>> I objected to conflating the API under a single method call.
>>
>> I'm talking about formats here. Perhaps you've misunderstood - I'm
>> only talking about logical/mental models here, not about the API
>> semantics.
>>
>> If JWK/PKCS#8 are sufficient for import/export, why are they not
>> sufficient for wrap/unwrap?
>
>
> IIUC, you're asking why an encrypted JWK or PKCS#8 object isn't sufficient
> as the wrapped key format (rather than using JWE).
>
> The only reason I know is that the JWK object is not a fixed size and so
> cannot be encrypted with a fixed size RSA-OAEP key (and noone likes
> RSA-KEM). You need to encrypt and integrity protect with randomly generated
> symmetric keys, encrypt those keys (or the key from which they were
> generated) with RSA-OAEP and then format the encrypted key, encrypted
> payload and integrity check into some kind of structure. JWE provides just
> that.

Sure.

And if you're using CMS, you do something similar, but different.

And if you're using [insert protocol here], you do something similar,
but different.

That's why I don't see why JOSE is intrinsic here - it seems like it's
just trying to be syntactic sugar.

The merits of that sugar bear discussing, certainly, but the goal of
this thread is to find out if that's all it is - sugar. From your
description of the steps, it sounds like you agree that it is - mod
the attributes discussion.

Correct?

>
> For a symmetric key encryption key the situation is simpler. I think you
> could just apply AES KW to the JWK, but the integrity protection is weak, I
> think.
>
>>
>>
>> >
>> >>
>> >>
>> >> Recall that we have the key formats "raw", "pkcs8", "spki", and "jwk".
>> >>
>> >> The current wrap/unwrap proposal can ONLY be used with JWKs, which
>> >> creates a divergence from the support for import/export, which
>> >> supports more than just JWK.
>> >
>> >
>> > Right, exactly because there are other formats that can represent raw
>> > keying
>> > material, but there aren't existing formats that can securely wrap the
>> > key
>> > and attributes together.
>> >
>> > Having said that, if you have a use case for wrapping other key formats
>> > it
>> > is indeed easy to add that by adding the KeyFormat field.
>>
>> Before we start making proposals for API changes, lets first make sure
>> we've actually discussed the problem. As discussed at the F2F this
>> week, it's very easy to make proposals that address a single members'
>> problem space, but fails to actually appreciate or establish what the
>> underlying issue is.
>>
>> >
>> >>
>> >>
>> >> Was this an arbitrary design decision, or are there some set of
>> >> technical requirements? It seems like the JOSE support (including
>> >> transliteration of JOSE algorithms, params, SPIs, etc) can all be
>> >> handled via polyfill, and that a simple, composed,
>> >> "export-but-then-encrypt" or "decrypt-and-then-import" is more robust
>> >> and useful.
>> >
>> >
>> > At least the mapping of algorithms and other WebCrypto Key attributes
>> > to/from JWK is needed for pure import/export in JWK format.
>>
>> This is something that's not been specified yet, and not something
>> that was clear to me that you were assuming would be the case.
>>
>> You see attributes being preserved via import/export - is this a
>> correct statement?
>
>
> Sure. JWK has key type, algorithm and use fields. I assume they should be
> populated on export and should not be ignored on import. Our proposal for
> wrap/unwrap adds an extractable field to JWK.

Thanks for clarifying. I'm not sure I agree with your description of
how import/export "should" work, but it's useful to understand your
assumptions here.

>
>>
>>
>> >
>> > Regarding the idea that the JWE object could be constructed by
>> > Javascript if
>> > the UA provides the necessary primitives: In addition to export+encrypt
>> > and
>> > decrypt+import we would also need primitives to wrap and unwrap the
>> > Content
>> > Master Key in the JWE structure.
>>
>> I'm sorry, why?
>>
>> The CEK (nee CMK) is simply a series of octets - this corresponds to
>> the 'raw' key type.
>>
>> generateKey - yields an appropriately sized CEK
>> wrapKey with raw - encrypts the set of octets that correspond to the
>> CEK and returns that.
>>
>> Why would the above be insufficient?
>
>
> That's fine. The problem is on the unwrap side. We need a primitive that can
> be used to decrypt+import the CEK into a non-extractable Key object, without
> there being the possibility for the JS to access the raw bytes of the CEK.

Sure. This is the hypothetical "unwrap" we're discussing.

That is, for keys protected with a CEK, you do two unwrap operations -
you unwrap the CEK with the recipient key, the unwrap the JWK with the
CEK.

>
>>
>>
>> Again, I'm exploring what a wrap/unwrap SHOULD look like, presuming
>> it's supported. Your current proposal has a series of assumptions
>> baked into the proposal, and I'm attempting to better understand them
>> to better understand the design.
>>
>> >
>> > For RSA-OAEP, the wrapping of the CMK is just RSA-OAEP encryption, so
>> > that
>> > would be decrypt+import with a key format which is the raw AES CMK
>> > bytes.
>> > For AES, the CMK is wrapped using AES Key Wrap, so we would need support
>> > for
>> > that. In both cases there needs to be a "usage" for decrypt+import that
>> > is
>> > separate from simple decryption, otherwise the key encryption key can be
>> > used to do just a decrypt, rather than a decrypt+import.
>>
>> As an aside, you made an unqualified statement here that is not
>> entirely obvious - why does there need to be a distinct usage / why is
>> it bad (since you imply it is) to be able to use a key for just
>> decrypt, rather than decrypt+import? For the purposes of understanding
>> your proposal, it would be good to explain this - but I suspect this
>> is correlated to the other thread related to why can't you polyfill
>> wrap/unwrap.
>
>
> As I say the point of wrap/unwrap is to deliver a key to an entity that has
> the key encryption key. If the key encryption key is not itself extractable
> we want to pass that property on to the keys that it unwraps.

I definitely don't agree with this. There's no reason to make that
extractability normatively viral.

Existing APIs do one of two things:
 - Extractability is fully in control of the calling/requesting
application. The security boundary for such APIs *includes* the
calling application (as, I would argue, ours does). In cases where a
key "shouldn't" be extractable, it's up to the *application* to be
well-behaved - and typically, audited.
 - Extractability is partially in control of the requesting
application, and partially in control of the implementing library.
That is, for a given wrapping key, it MAY allow keys it unwraps to be
extractable or not. The calling application specifies what it WANTS,
and the library then makes a backend policy evaluation as to whether
or not that request can be satisfied.

Given the design of the Web Crypto API, I strongly believe the former
is the appropriate for the base specification. For extensions (such as
pre-provisioned keys) that attempt to move more security policy into
the UA, I think it's reasonable for the UA to describe a set of
policies that can cause such operations to fail *when dealing with
such keys*.

This goes back to the "separate spec" discussion. I think in the model
where the application is trusted, which is the model we've tried to
design for, so far, given as how it's entirely consistent with the web
model, it's entirely reasonable to only specify the former. In the
case of keys that which to fundamentally alter the security
properties, I think they should be responsible for dealing how such
keys interact.

> That is, they
> should also not be extractable and as a consequence the keying material
> should not be visible to the JS. That seems reasonable if the extractable
> property has any value at all (you seem to be leaning towards an argument
> which implies it does not).
>
> Why does this mean there needs to be a distinct usage ? If there was not,
> then the key encryption key could simply be used to decrypt the wrapped key
> (or rather the CEK), effectively "extracting" the wrapped key, which we have
> just said should not be extractable.
>
>>
>>
>> The argument you've made suggests you read *this* message as arguing
>> against wrap/unwrap. That's not the case. I'm trying to explore what
>> wrap SHOULD look like, IF it is to be supported. The current
>> wrap/unwrap bakes in format assumptions, without fully explaining why
>> or their use case. That's the intent of this message.
>
>
> Sure. My argument above was attempting to explain why decrypt+import and
> encrypt+export doesn't (quite) work for the JWE format, and thus why a
> format assumption was baked in to the proposal. With some changes I could
> see how a decrypt+import and encrypt+export approach could work, but it
> becomes quite complex. I'm just not sure that's a good way to factor this
> problem.
>
>>
>> For example, your current proposal fails to address the requirements
>> you set forward in
>> http://www.w3.org/2012/webcrypto/wiki/KeyWrap_Proposal - namely, #3 on
>> Requirements, that it supports the same formats import/export support.
>> I'm trying to explore why that is.
>
>
> Ah, that would be because I forgot to update that when it seemed from the
> list discussion that there was no demand for other formats ;-)
>
> Note that supporting JWE-encrypted-X within the current proposal instead of
> only JWE-encrypted-JWK is simple and I'd have no problem with that (if
> there's a use-case). There would still be a "wrapping format" assumption, if
> not a "key format" assumption. The "wrapping format" assumption is what I
> address above.
>
> So, just to be clear, there are two format assumptions: a wrapping format
> where we propose JWE and a key format where we propose JWK. Supporting
> multiple key formats is straightforward. Supporting other wrapping formats
> is also simple to add. Re-factoring so that wrapping format becomes an issue
> for the script is possible but trickier.
>
>>
>> If it helps you to understand the question I'm asking, presume you had
>> some distinct key usage for "wrap"/"unwrap". With such a usage, why
>> does the format itself matter?
>
>
> If the question is whether I could build some kind of wrap/unwrap in JS with
> the properties I want using
> - decrypt+import and encrypt+export primitives (attached to their own
> usages) and
> - the existing WebCrypto algorithms
> - the existing WebCrypto key formats (including JWK with attribute mapping)
>
> then I believe the answer is yes.

>
> But if the question is whether I could build the JWE-protected-JWK format in
> JS with these primitives the answer is no. The reasons are:
> (i) the method JWE uses to wrap the CEK doesn't include attributes (yet)

Sounds like an issue for JOSE. However, the ability to "describe" raw
key material (eg: what is currently used in JWE) DOES exist as a
format in the current API - it's called "raw".

> (ii) we don't have a key derivation algorithm that matchs the way JWE
> derives the encryption and HMAC keys from the CEK

This sounds like ACTION-84 / ISSUE-12

> (iii) we don't have AES Key Wrap

Reasonable point that we should look at IF we support key wrap. That's
the gating factor.

> (iv) we don't have the AES CBC + HMAC SHA-1 authenticated encryption
> algorithm specified for JWE and we can't build it out of the separate AES
> CBC and HMAC SHA-1 WebCrypto algorithms (because the JS could just skip the
> integrity check and so integrity protection all the way to the entity with
> the key encryption key is broken).

I'm not sure I follow this point, but perhaps you're baking in some
hidden assumptions here again.

IF you DO trust the web application, this should be possible, right?

IF you DON'T trust the web application, what's the affect of skipping
the application skipping integrity check? It *seems* like your concern
would be then such an application would specify attributes you would
prefer not specified. Correct?

I don't see why the HMAC-SHA-1 construction, as used by JOSE, doesn't
work. Also, AIUI, they're looking at changing that construction to be
compatible with mcgrew (
http://tools.ietf.org/html/draft-mcgrew-aead-aes-cbc-hmac-sha2-01 ),
if not already, and that should have the same semantic equivalence as
AES-GCM.

>
> Now, all these could be addressed: (ii) and (iii) are easy to add and for
> (iv) we could just use AES GCM instead.
>
>>
>> > The problem is that
>> > there is no usage associated with the wrapped CMK. The JS could
>> > decrypt+import the CMK with a usage of decrypt, allowing the JWE payload
>> > to
>> > then be decrypted and returned to the script. That might be resolved
>> > with
>> > Richard's proposal that the CMK be represented as a JWK object, though
>> > I'm
>> > not sure that you don't eventually have the same problem when his
>> > recursion
>> > terminates.
>> >
>> > For the case where the payload is protected with AES-GCM, there's
>> > additional
>> > authentication data to take care of.
>>
>> Please explain why this is an issue, or why the current ability to
>> supply AAD when using AES-GCM is insufficient. See
>>
>> https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#dfn-AesGcmParams
>
>
> Yeah, I think this is ok. It's just something we have to consider.
>
>>
>>
>>
>> > For the case where the payload is
>> > AES-CBC + HMAC protected then you have to deal with deriving the
>> > encryption
>> > key and the MAC key from the Content Master Key.
>>
>> Please explain why this is an issue, or why the current ability to
>> perform key derivation is insufficient.
>
>
> As noted above, it's fine if I'm to craft my own wrap/unwrap format based on
> the caapbilities WebCrypto offers, but WebCrypto doesn't offer the
> capabilities needed to do JWE-encrypted-JWK. Not that they are hard to add.
>
>>
>>
>> Note, Richard and Vijay have already taken an action item to explore
>> this, and we already have a dedicated call set up to explore key
>> derivation, as this extends beyond the JOSE case.
>
>
>
>
>>
>>
>> So the question to you is - how or why is this different from the use
>> cases we discussed at the F2F and which were identified that are fully
>> independent of JOSE.
>
>
> I think this is answered above.
>
>>
>>
>> >
>> > So, I think it's not possible to do with the present JWE format and even
>> > if
>> > that is changed the operation doesn't factor well like this - you end up
>> > with a number of additional primitives and I'm not sure the complexity
>> > cost
>> > is worth the gain which is only partial decoupling from JOSE.
>>
>> The only coupling to JOSE, as I see it, is in translating the JWK.
>>
>> I *only* see UAs being required to understand "kty". As noted in the
>> JWK, all other fields are OPTIONAL, and that is the ONLY field needed
>> to understand the remaining structure from
>>
>> http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-10#section-5
>>
>> It seems you expect UAs MUST understand other parameters, but this is
>> not clear from http://www.w3.org/2012/webcrypto/wiki/KeyWrap_Proposal
>> #4-#6 Requirements
>
>
> Ok, I can add this.

Helps to evaluate your proposal, certainly, but I think it highlights
perhaps the fundamental disagreement (raised above and, apparently,
below) :)

>
>>
>>
>> >
>> >>
>> >>
>> >> For example, the current proposal of wrap/unwrap would effectively
>> >> prevent any security benefits from being realized from applications
>> >> which use PKCS#11, as they make use of PKCS#8 ( see
>> >> http://www.cryptsoft.com/pkcs11doc/STANDARD/pkcs-11v2-30m1-d7.pdf ,
>> >> Section 6.5 ). Likewise, CNG equally supports PKCS#8 ( see
>> >>
>> >>
>> >> http://msdn.microsoft.com/en-us/library/windows/desktop/aa376263(v=vs.85).aspx
>> >> ).
>> >
>> >
>> > I'm not sure there *are* any security benefits to be gained from key
>> > wrapping/unwrapping if the WebCrypto attributes - specifically
>> > extractable
>> > and usages - are not also protected within the wrapper. In that case you
>> > might as well do decrypt and then import in JS.
>>
>> Agreed. And I don't see the protection of attributes as being part of
>> wrap/unwrap.
>>
>> This matches the existing cryptographic APIs that such implementations
>> will be built on.
>>
>> The assumption of the Web Crypto API is the same assumptions made by
>> native code dealing with 'native' APIs like CAPI/CNG/PKCS#11/CDSA/etc
>> - that is, the application performing the operation is, itself,
>> trusted.
>>
>> To restate, my view of support for JWK within import/export is that
>> the *only* attribute that MUST be understood by a UA is "kty" - since
>> that's necessary to extract the actual key material. All other
>> attributes MAY be ignored.
>
>
> If you also apply that to wrap/unwrap we have a pretty fundamental
> disagreement, then. (For import/export it's moot because the contents of the
> JWK can be modified by the script).
>
> Btw, I'm going to be on vacation for a week from - well, about now - so if
> you don't hear much from me for a while, that will be why.
>
> ...Mark

Great, I think this gets to the heart of the matter.

The proposal for wrap/unwrap is predicated on:
- Not treating the web application as part of the security boundary
- Wanting to preserve attributes across the security boundary

If the application IS part of the security boundary (a view I see as
necessary for the low-level API), then it's possible to preserve
attributes across boundaries - thus, it's possible to fully polyfill
wrap/unwrap.

Is this a good summary of our disagreement?

Received on Saturday, 27 April 2013 01:01:32 UTC