JWK import/export as ECMAScript objects, rather than ArrayBuffer

The motivation:

* Provide a means of easy interchange with Web Sockets (eg: by allowing
Text Frame, rather than imposing Binary Frame, as done by send(ArrayBuffer)
)
* Provide a means of easy interchange of JWK with postMessage (eg: by not
requiring a Key object itself be posted)
* Provide a means of easy integration with larger JSON-backed messages

That is, presume a structure
{
  'larger_message': 'something',
  'jwk': [{
    'kid': 'foo',
    'alg': 'RSA',
    'kty': 'RSA1_5',
    'n': '....',
    'e': '....'
  }]
}

Under the current API, one has two options - depending on UA support for
http://encoding.spec.whatwg.org/#api

With Encoding support:

// Makes 3 additional copies of message.jwk
// 1 for the .stringify
// 1 for the TextEncoder
// 1 for the importKey (cloning the ArrayBuffer)
// By definition, this copies *all* fields of message.jwk, including those
not used by importKey (eg: 'kid')

message = JSON.parse(message);
jwkBuf = (new TextEncoder("utf-8")).encode(JSON.stringify(message.jwk));
window.crypto.subtle.importKey("jwk", jwkBuf, { name: "RSAES-PKCS1-v1_5" },
[ "encrypt", "decrypt"] );

Without Encoding support:
It's necessary to do something like strToUTF8Arr (
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding)

Under the proposed API, one simply does

// Makes 1 additional copy of message.jwk
// 1 for the importKey (cloning message.jwk)
// By definition, this *does not* copy all fields of message.jwk - only
those fields used for the import (eg: 'kid' is NOT copied)
window.crypto.subtle.importKey("jwk", message.jwk, { name:
"RSAES-PKCS1-v1_5" }, [ "encrypt", "decrypt" ]);


Types used:

dictionary JwkKeyDictionary {
  DOMString kty;
  DOMString alg;
  boolean ext;
  DOMString[] usages;
};

dictionary JwkEcKeyDictionary : JwkKeyDictionary {
  DOMString crv;
  DOMString x;
  DOMString y;
  DOMString d;
};

dictionary JwkRsaOtherPrimeDictionary {
  DOMString r;
  DOMString d;
  DOMString t;
};

dictionary JwkRsaKeyDictionary : JwkKeyDictionary {
  DOMString n;
  DOMString e;
  DOMString d;
  DOMString p;
  DOMString dp;
  DOMString dq;
  DOMString qi;
  JwkRsaOtherPrimeDictionary[] oth;
};



Changes to signatures:
Old:
Promise<any> importKey(KeyFormat format, CryptoOperationData keyData,
AlgorithmIdentifier? algorithm, boolean extractable, KeyUsage[] keyUsages);
Promise<any> exportKey(KeyFormat format, Key key);

New:
Promise<any> importKey(KeyFormat format, (CryptoOperationData or
JwkRsaKeyDictionary or JwkEcKeyDictionary), AlgorithmIdentifier algorithm,
boolean extractable, KeyUsage[] keyUsages);
Promise<any> exportKey(KeyFormat format, Key key);


Changes to algorithms:
Wrap Key ( 14.3.1 /
https://dvcs.w3.org/hg/webcrypto-api/raw-file/3f7df730b2c7/spec/Overview.html#SubtleCrypto-method-wrapKey)

12.
* If format is "spki":
  - Let bytes be the result of performing the export key operation
specified the algorithm attribute of key using key and format.
* If format is "pkcs8"
  - Let bytes be the result of performing the export key operation
specified the algorithm attribute of key using key and format.
* If format is "jwk"
  - Let object be the result of performing the export key operation
specified by the algorithm attribute of key using key and format.
  - Let stringifiedJwk be the result of invoking the JSON.stringify method
specified in Section 15.12.3 of [ECMA-252], with /object/ as /value/.
  - Let bytes be the UTF-8 encoding of stringifiedJwk


>From the algorithm-specific import key sections eg: using
https://dvcs.w3.org/hg/webcrypto-api/raw-file/3f7df730b2c7/spec/Overview.html#rsassa-pkcs1-operationsas
an example

4. If format is "jwk"
  1. If /keyData/ is not an instance of a JwkRsaKeyDictionary, return an
error ...
  2. Let /jwk/ be /keyData/

>From the algorithm-specific export key sections - eg: using again
RSASSA-PKCS1

4. If format is "jwk"
  * Let /jwk/ be a new ECMAScript object created as if by the expression
({})
  * _Set the property "n" of /jwk/_ to the _base64url-encoded_ modulus of
the RSA public key represented by /key/, as specified by Section 6.3.1 of
[JWA]
  * _Set the property "e" of /jwk/_ to the _base64url-encoded_ big integer
exponent representation of the RSA public key represented by /key/, as
specified by Section 6.3.1 of [JWA]
  ...
  * Let /result/ be /jwk/

Terminology:
When this specification says Set the property /name/ of /object/ to
/value/, call the [[DefineOwnProperty]] internal method of /object/ with
property name /name/, the Property Descriptor { [[Writable]]: true,
[[Enumerable]]: true, [[Configurable]]: true, [[Value]]: /value/ }, and the
Boolean flag false.

Received on Wednesday, 12 March 2014 00:23:13 UTC