W3C home > Mailing lists > Public > public-webcrypto@w3.org > October 2012

Re: Proposal for ISSUE-25 (Globally unique pre-shared keys)

From: Ryan Sleevi <sleevi@google.com>
Date: Mon, 29 Oct 2012 08:10:46 -0700
Message-ID: <CACvaWvYmPAje6H2-BcZoydmuFF2UftKaUeV-84yShesQ391agw@mail.gmail.com>
To: Mark Watson <watsonm@netflix.com>
Cc: "public-webcrypto@w3.org Group" <public-webcrypto@w3.org>
On Mon, Oct 29, 2012 at 7:48 AM, Mark Watson <watsonm@netflix.com> wrote:
>
> On Oct 29, 2012, at 2:41 PM, Ryan Sleevi wrote:
>
>> On Mon, Oct 29, 2012 at 6:23 AM, Mark Watson <watsonm@netflix.com> wrote:
>>> All,
>>>
>>> To address ISSUE-25 [1] I'd like to propose the following changes. I hope we
>>> can discuss this later in the week.
>>>
>>> 1) To Section 6, Privacy Considerations, replace the last sentence of the
>>> "Super-cookies" section ('This is especially true for keys that were
>>> pre-provisioned for particular origins and for which no user interaction was
>>> provided') with a more detailed separate section:
>>>
>>> "Pre-shared keys
>>>
>>> Pre-shared keys may be long-lived and may be securely associated with
>>> specific hardware elements. Without sufficient safeguards it may be possible
>>> for an origin to identify a user or device without the knowledge or consent
>>> of the user. Access to pre-shared keys SHOULD require explicit user
>>> authorization on a per origin basis. User Agents supporting pre-shared keys
>>> SHOULD ensure that each origin receives a unique origin-specific pre-shared
>>> key. This could be accomplished, for example, by transforming an
>>> origin-independent secret using a suitable origin-specific one-way
>>> function."
>>
>> My initial reaction regarding the transformation is that while it's
>> good, I'm not sure how reasonable it may be to recommend at a SHOULD
>> level.
>
> The "transformation" was just an example of how an implementor could follow the SHOULD recommendation. The recommendation is to make sure pre-shared keys are different across origins. Another way would be to only support pre-shared keys that were explicitly provisioned separately for each origin. Another way would be for an implementor to have a back-end service which they use to obtain new keys when they need them etc.

Yes, but you seem to have been designing this API with the assumption
there is some master key which is then used to derive origin-specific
keys. Based on your past descriptions of the Netflix architecture,
this seems a reasonable extrapolation, and is equally reflected in the
concerns regarding user access.

But that's not something that I think is general to pre-shared or
pre-provisioned keys. Both pre-shared and pre-provisioned keys may
already be origin-provisioned, thus there is no need for some form of
derivation function. That is, the language "pre-shared keys"
implicitly presumes (global? user-specific? multi-origin?) pre-shared
keys, and then describes a function on how to get "unique
origin-specific pre-shared keys".

It seems to me that your requirements for both user-access and
derivation are thus *not* related to pre-shared/pre-provisioned keys,
but more generally concerns regarding keys shared between origins.
That's why I think it's a weird fit for where you put it.

As well, there are potentially cases where access to the "master" key
material (that is, the key material **as provisioned**) is desired,
but the current recommendation seems to aggressively discourage that.
If the key material is not shared between origins, is that still a
concern?

>
>> In the case of smart card keys (for example), such
>> transformation may not be acceptable or possible - since access to the
>> key material is generally not available.
>
> Sure. As per ISSUE-19, keys with this origin-specific property have different privacy properties than those which might be shared across origins, even with user consent. I'm not claiming to have answers to the privacy issues associated with the later, but I'm keen that we support the former.

Right - so this really is a distinction between origin-specific and
origin-shared keys, and not pre-shared vs generated keys.

>
>> It's also only really
>> applicable to symmetric keys (which generally lack any particular
>> structure), rather than asymmetric keys (which must follow some form
>> of mathematical construct)
>
> Yes. That paragraph should be restricted to symmetric keys. For asymmetric keys I think you need to one of the other two approaches I mentioned above.

Or neither.

>>
>> It *sounds* like you think of pre-shared keys as being symmetric only,
>> but I'm not sure I'd agree with that.
>
> That's the use-case we're most interested in but I didn't intent to make the text restrictive.
>
>>
>>>
>>> 2) To Section 10 (Key interface) [or wherever is most appropriate], add new
>>> sub-section, as follows:
>>>
>>> "10.2 Pre-shared keys
>>>
>>> User Agents MAY expose origin-specific pre-shared keys as Key objects
>>> visible within the keys attribute of the Crypto interface. Examples of
>>> pre-shared keys include keys stored in secure hardware elements.
>>
>> I'm working on a proposal to fully remove the window.keys interface,
>> which I believe is the right approach. So we'll need to re-consider
>> the pre-provisioned key case.
>
> I'll read your mail and respond to that.
>
>>
>> Note - I think of the general issue being pre-provisioned (eg:
>> including symmetric and asymmetric), and not pre-shared (which implies
>> symmetric only, as a general term of art)
>
> Ah, ok, I wasn't aware of the terminology restriction. Most of my text should be changed to pre-provisoned, then.
>
>>
>>>
>>> 10.2.1 Pre-shared key pairs and certificates
>>>
>>> Where a pre-shared public/private key pair has an associated X.509
>>> certificate, this certificate SHOULD be made available in a property named
>>> "x509certificate" within the extra attribute of the Key object. The
>>> "x509certificate" property contains the base64 encoding of the … <specify
>>> encoding of X.509 certificate here>.
>>
>> I really think this as problematic - for the various reasons we've
>> discussed during certificate. Minimally, we'd need to consider this as
>> an array, but I think practical/implementation concerns mean this is
>> not generally possible. For example, a key may be stored in one device
>> but a certificate stored in another device.
>
> Can you elaborate ? I am thinking of a very simple, dumb, capability that just exposes the bytes of the encoded X.509 certificate, if it's available in the same place as the key.

I'm saying that the certificates associated with a key may not be
stored with the key itself, nor is it a static list. For example, new
certificates may be deployed via application/x-x509-user-cert (for
user agents supporting it) at any point. What is the value of the
attribute as keys are added? As they're removed?

Does accessing the object force the user agent to query all (external)
certificate storage mechanisms to discover if any certificates have
been added or removed? I fear under the current language, it does, and
that's not an acceptable solution.

Alternatively, it requires the user agent to store within its own
persistence store a static list of all associated certificates with a
key, and that's not a solution I can see as workable either.

>
>>
>> I'm also very loathe to expose attributes that are stored/managed on
>> security devices. The current (albiet synchronous) API is primarily
>> designed for attributes read/set by authors, and perhaps is a poor fit
>> for exposing pre-provisioned key attributes of meaningful semantic
>> form.
>
> The two issues of "whether to expose attributes stored/managed on security devices" and "how to expose them on the API" are separate issues. The second should not dictate the first. If we want to expose them, then we can design an API that works for that (presumably with some asynchronous component).

I'm not sure if I agree or disagree with your point here.

Certificates, to me, are attributes that are stored/managed on
security devices. Therefore, IF we want to expose them (and I think we
do have general consensus that we do), THEN we need to define the API,
which I view your proposal as the 'certificate[s]' attribute as doing.
And I don't think that API is a good API, for the reasons expressed
previously and above.

>
>>
>> Case in point: A key stored on a smart card may have multiple
>> certificates issued, with various lifetimes and purposes, even though
>> they use the same key, such as cross-certified by different
>> organizations.
>
> Ok, so the attribute should be "certificates" and be an array of certificates.
>
>>
>>>
>>> 10.2.2 Pre-shared symmetric keys and identities
>>>
>>> Where a pre-shared symmetric key has an associated globally unique identity,
>>> this identity SHOULD be made available in a property named "uid" within the
>>> extra attribute of the Key object. The "uid" property contains the base64
>>> encoding of the bytes of the globally unique identity."
>>
>> As I mentioned on IRC during the proposed wording, and as mentioned
>> during previous conversations, my big concern here is that there's
>> absolutely no definition of what a "globally unique identity" is, nor
>> how an implementor can determine, for the various forms of key storage
>> supported (whether hardware or software), if a given identifier is a
>> "globally unique ID"
>
> There are many cases where there will only be one choice, or where the choice is obvious.
>
> But even if the choices made by implementors are arbitrary, then this is still useful. In some cases an implementor will tell me the keys they have put into devices and the identities they associated with them. In another case, all I want to learn from the implementor is what properties the identities have, since I am more interested in knowing when the same X visits again than which X it was (where X is the thing the identifier identifies).

Respectfully, I think the point "If the choices made by implementors
are arbitrary, then this is still useful" is wrong. I think arbitrary
choices make this useless and dangerous to the spec, because it
provides effectively no portability for implementations in terms of
something spec'd in the standard. This is exactly why we're trying to
define, as absolutely and concretely as possible, how RSA, AES, ECC,
etc are performed - so that they're compatible across implementations.

While I realize there's an implementation dependence in terms of what
algorithms are implemented, I think we want to absolutely avoid
situations where "The same thing behaves differently on different
APIs". If you want to get into implementation-dependent free-for-all,
then it should not be normatively (or, arguably, informatively) spec'd
via the API, because it provides zero guidance for implementors and
misleads users.

>
> I can see two kinds of problem arising from functional decompositions:
>
> 1) A SmartCard API just provides you with a bag of attributes, potentially different ones for each SmartCard inserted. Which one do you expose as "uid". I'd suggest in this case none of them. The fact that different SmartCards might have completely different attributes is a bigger problem.

Agreed ;)

>
> 2) The API for some some secure element on Platform A exposes xid and yid. The API for the same kind of secure element on Platform B exposes pid and qid. Again, there's a deeper problem here which I'm not purporting to solve.

And that's why I feel, without solving it, it shouldn't be in the spec
as some form of standard (normative or informative) behaviour.

>
>
>>
>> For example, in PKCS#11, there is no such global *or* unique ID
>> requirement. Typically, such attributes are embedded in vendor ID
>> attributes that are specific to the hardware vendor, the middleware
>> being used, the version of the card being used, the provisioning
>> profile, etc. So it's reasonably impossible for a generic
>> implementation to reliably determine what construction constitutes a
>> "globally unique identity"
>
> Agreed. That's fine. Don't expose a "uid" attribute in that case.
>
>>
>> Further, it doesn't help that some "globally unique identities" are
>> the combinations of several attributes that, together, provide the
>> unique identifier. The fact that a key has a globally unique
>> identifier formed through the combination of n-number of attributes
>> creates ambiguity for implementations in determining if and how this
>> should be exposed to applications.
>>
>> As such, unless we're defining exact storage semantics (which we're
>> not, at least so far), or defining exactly how pre-shared keys are
>> implemented (which, I would hope, we're not), then I'm not sure we can
>> reasonably or reliably provide this sort of statement.
>
> The statement has a pre-condition ("where and identity exists") and is a SHOULD not a MUST. There is plenty of get-out for the ambiguous cases, but a simple recommendation for the simple case.
>
>>
>> Minimally though, I think the above wording MUST specify how an
>> implementation can determine if a "globally unique identifier" is
>> present for a pre-shared key, and I personally believe that's an
>> intractable task.
>
> I think we could give guidance, but since the whole requirement is a recommendation I don't see any need for requirement-level text.
>
> Guidance would be along the lines of saying that if a key has an associated identifier which is defined to be unique amongst all similar keys, this should be chosen as the "uid" identifier. In your examples above, there is no such identifier.
>
> …Mark
>
>>
>

As an implementor, I think the only time the "uid" can be reasonably
exposed then is by Netflix and those working with Netflix. The
proposed wording provides no guidance whatsoever for Mozilla,
Microsoft, Chromium, Apple, Opera, Intel, or any other potential
implementor. It's fully compliant with the spec to not implement it.
It's fully compliant with the spec to implement different things. It
does not resolve the issues with UA sniffing that you raised in the
past, it does not resolve the issues with UA portability. In short,
it's a specific solution for a specific UA, and I don't think that's a
good thing to add.

IF we could come up with language that could be followed by all
implementors and lead to the same result, I think that's a good thing
and it's worth considering. But I think that's only possible by
defining exactly how to determine if a key has a uid, and that
requires enumerating all types of keys (past, present, and future), OR
defining that only certain keys have a uid, and neither of those are
really desirable to put in the spec IMO.
Received on Monday, 29 October 2012 15:11:19 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 29 October 2012 15:11:19 GMT