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

RE: Proposal for key wrap/unwrap (ISSUE-35)

From: Acar, Tolga <tolga.acar@intel.com>
Date: Tue, 30 Oct 2012 17:16:16 +0000
To: Mark Watson <watsonm@netflix.com>, Ryan Sleevi <sleevi@google.com>
CC: "public-webcrypto@w3.org Group" <public-webcrypto@w3.org>
Message-ID: <52337C44538F2F4D87D63A3E46538A87BBAAA5@FMSMSX106.amr.corp.intel.com>
Mark,

This looks like a proposal I sent to Ryan, Vijay, Wan-The, and Brian - except that my proposal specified a WrapKey and UnwrapKey intefaces instead of reusing the Import/Export interfaces. I am OK either way. One of the places Ryan and I ended up is the need of defining the wrapped key blob format.

For completeness, here is what I had written, with more comments inline.

interface KeyWrapper : KeyOperation {
  // Wrapping key.
  readonly attribute Key wrappingKey;

  // Wrapping algorithm to use with the wrappingKey.
  readonly AlgorithmIdentifier algorithm;

  // Wrap the "keyToWrap" with the "wrappingKey" using "algorithm".
  // The wrapped key is in KeyOperation's result as ArrayBufferView.
  // Recommended algorithms: must include confidentiality and integrity protection,
  // e.g., AES-GCM, AES-CCM.
  // It is possible to define hybrid algorithms such as "AES-CBC + HMAC",
  // but this document does not specify them.
  void WrapKey(Key keyToWrap);
};

interface KeyUnwrapper : KeyOperation {
  // Unwrapping key.
  readonly attribute Key unwrappingKey;

  // Unwrapping algorithm to use with the unwrappingKey.
  readonly attribute AlgorithmIdentifier? algorithm;

  // Unwrap an input buffer to create a key object.
  // Wrapping "algorithm" may be explicitly given or can be parsed from the input buffer.
  // If the unwrapping algorithm is specified, it is checked against the decoded
  // algorithm from the input buffer for equality.
  // The unwraped Key object is in KeyOperation "result" attribute.
  void UnwrapKey(ArrayBufferView inputBuffer);
};

//
// The Crypto interface must be augmented with the following methods.
//
interface Crypto {
  // Include other methods, shipped for brevity.

  KeyWrapper createKeyWrapper(Key wrappingKey,
			      AlgorithmIdentifier algorithm);
  
  KeyUnwrapper createKeyUnwrapper(Key unwrappingKey,
				  AlgorithmIdentifier? algorithm = null);
};


More comments inline.

> -----Original Message-----
> From: Mark Watson [mailto:watsonm@netflix.com]
> Sent: Tuesday, October 30, 2012 3:26 AM
> To: Ryan Sleevi
> Cc: public-webcrypto@w3.org Group
> Subject: Re: Proposal for key wrap/unwrap (ISSUE-35)

<snip for brevity>

> >> Implementations SHOULD support additional JSON Web Key members of:
> >>  * extractable (boolean indicating extractability)  * startdate (key
> >> start date in seconds since the epoch)  * enddate (key end date in
> >> seconds since the epoch)
> >
> > Can you explain the difference between wrap and extractable here? In
> > practical security considerations, they're better considered equal.
> 
> Do you mean that there is little point in wrapping a key if it is then
> immediately extractable ? That would be true if there was a difference in
> trust level between the UA and the client application, as there is in our use-
> cases, so from my point of view we could say that exportable is always false
> when unwrapping a key.
> 
> But I can imagine other use-cases where the script is entitled to access the
> key after unwrap, but there is still some reason it was wrapped (for example
> for transport or storage).
Exportable can be true or false in a wrapped key, and they are indeed different.
Yes on key transport of a wrapped key. Also, if I want to make sure that a key is never extracted in a code with some level of assurance, and if a big chunk of my assurance comes from code inspection, automated or otherwise, I can check that the code does not extract a key.
One can also make an argument that separating WrapKey and ExportKey-with-wrapping-functionality makes this code "inspection" more reliable; but I am not that keen to push this separation.


> >> "18. Crypto interface
> >>
> >> KeyImporter createKeyImporter( KeyFormat format, ArrayBufferView
> key,
> >> AlgorithmIdentifier? keyAlgorithm, AlgorithmIdentifier?
> >> wrapAlgorithm, Key? wrappingKey, bool temporary = true, bool
> >> extractable = false, KeyUsage[] keyUsages = [] );

Let me also comment on the key attributes during key import (unwrap, that is). Instead of the application calling the key importer API to specify key attributes, I think a wrapped key format must carry the key's attributes in the wrapped key blob, so that they are decoded and attached to the key during import. This preserves a key's attributes across various implementations and instances. Otherwise, an application would have to transfer those attributes somehow, or set them as it sees fit, which may or may not abide by the key's attributes determined at key generation/derivation time. 
Given this, the keyAlgorithm seems redundant if that is already in the wrapped key blob - I know you allow the keyAlgorithm to be null and let that be decoded from the wrapped key blob. I am saying that algorithm MUST come from the wrapped blob; even if it is empty. Is there a case where the app would need to override the key algorithm during import? I am worried about integrity of key's attributes.


> >> "18.1.8 The createKeyImporter method
> >>
> >> The createKeyImporter method returns a new KeyImporter object that
> >> will import new keys of the, potentially wrapped, specified
> >> KeyFormat. It must act as
> >> follows:
> >>
> >>  1. If keyAlgorithm is specified, let normalizedKeyAlgorithm be the
> >> result of processing keyAlgorithm according to
> >>     the algorithm normalizing rules.
> >>  2.  If keyAlgorithm is specified and if normalizedKeyAlgorithm does
> >> not describe a registered algorithm throw a
> >>     NotSupportedError and terminate the operation.
> >>  3. If wrapAlgorithm is specified, let normalizedWrapAlgorithm be the
> >> result of processing wrapAlgorithm according to
> >>     the algorithm normalizing rules.
> >>  4.  If wrapAlgorithm is specified and if normalizedWrapAlgorithm
> >> does not describe a registered algorithm throw a
> >>     NotSupportedError and terminate the operation.
> >>  5. Return a new KeyImporter object S with the following characteristics:
> >>     1. S.result = null
> >>     2. S.format = format
> >>     3. S.wrapped = true if wrapAlgorithm is not null, false otherwise
> >>
> >> Imported keys SHALL be subject to the extraction and usage
> >> constraints of the key data, if any. The temporary argument SHALL be
> >> honored. The extractable argument SHALL NOT be honored if the key
> >> data does not allow extraction of the imported key. The imported
> >> key's usages SHALL consist of the intersection of the keyUsages
> >> argument and the usages specified in the key data of the imported
> >> key.
Ah, I see your intersection argument Re: key attributes comment above. 

<snip more>
Received on Wednesday, 31 October 2012 08:25:31 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Wednesday, 31 October 2012 08:25:39 GMT