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

On Fri, Apr 26, 2013 at 6:01 PM, Ryan Sleevi <sleevi@google.com> wrote:

> 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?
>

Let's discuss on our next call, after I get back.

I believe the above is roughly correct about the point of disagreement, but
to fully understand your position I need to understand how the extractable
flag fits into your view of the situation ? How is that valuable if there
is no boundary at all between JS and UA for the purposes of this API ?

I agree that there are situations where the UA/JS boundary is unimportant
and situations where it is significant but I don't agree that the
difference is tied fundamentally to the presence or absence of
pre-provisioned keys. Of course pre-provisioned keys make a big difference,
but from a *practical* security engineering standpoint the JS and the UA
are different in all cases. They are subject to different attacks. They
have different security properties. If we make a fundamental assumption
that they are the same (for this API), we are pre-judging the security
engineers who will actually use this API. That's not our job. Unless we
have a mathematical reason to believe that there is no boundary of interest
here the people who will decide whether it matters to their application are
the engineers using the API.

...Mark

PS: I didn't answer your other points above only because I am going on
vacation. I'll get back to you on those.

Received on Saturday, 27 April 2013 13:40:58 UTC